ghosthunter5 2021-06-28 12:07 采纳率: 60%
浏览 129
已采纳

MSP430g2553如何将电阻值按一定周期采样并通过串口输出至主机的串口调试助手?

#include"MSP430G2553.h"
#include "Slope.h"
#include "TCA6416A.h"
#include "HT1621.h"
#include "LCD_128.h"
#include "stdint.h"

unsigned char Key=0;		//轮盘电位器的电阻等效按键值
//-----待测“传感器电阻”的分档值,实际接入了5k定值电阻+10k轮盘电位器-----
const unsigned char R_Class[8]={55,67,82,97,113,128,138,144};		//单位为百欧

void WDT_OnTime();
void Slope_R_Dect();			//测得待测电阻后的事件处理函数
void TCA6416A_LED(unsigned char num);		//LED灯柱显示函数
void Display_SLOPE();
void Display_RSENS(unsigned char Rsens);
/*
 * @fn:		void InitUART(void)
 * @brief:	初始化串口,包括设置波特率,数据位,校验位等
 * @para:	none
 * @return:	none
 * @comment:初始化串口
 */
void InitUART(void)
{
	/*SMCLK时钟源为DCO*/
	BCSCTL2 &= ~SELS;
	/*SMCLK分频系数*/
	BCSCTL2 &= ~(DIVS0 | DIVS1);
    /*复位USCI_Ax*/
    UCA0CTL1 |= UCSWRST;

    /*选择USCI_Ax为UART模式*/
    UCA0CTL0 &= ~UCSYNC;

    /*配置UART时钟源为SMCLK*/
    UCA0CTL1 |= UCSSEL1;

    /*配置波特率为9600@1MHz*/
    UCA0BR0 = 0x68;
    UCA0BR1 = 0x00;
    UCA0MCTL = 1 << 1;
    /*使能端口复用*/
    P1SEL |= BIT1 + BIT2;
    P1SEL2 |= BIT1 + BIT2;
    /*清除复位位,使能UART*/
    UCA0CTL1 &= ~UCSWRST;
}
/*
 * @fn:		void UARTSendString(uint8_t *pbuff,uint8_t num)
 * @brief:	通过串口发送字符串
 * @para:	pbuff:指向要发送字符串的指针
 * 			num:要发送的字符个数
 * @return:	none
 * @comment:通过串口发送字符串
 */
void UARTSendString(uint8_t *pbuff,uint8_t num)
{
	uint8_t cnt = 0;
	for(cnt = 0;cnt < num;cnt ++)
	{
		while(UCA0STAT & UCBUSY);
		//__delay_cycles(5000);
		UCA0TXBUF = *(pbuff + cnt);
	}
}
/*
 * @fn:		void PrintNumber(uint16_t num)
 * @brief:	通过串口发送数字
 * @para:	num:变量
 * @return:	none
 * @comment:通过串口发送数字
 */
void PrintNumber(uint16_t num)
{
	uint8_t buff[4] = {0,0,0,'\n'};
	uint8_t cnt = 0;
	for(cnt = 0;cnt < 3;cnt ++)
	{
		buff[2 - cnt] = (uint8_t)(num % 10 + '0');
		num /= 10;
	}
	UARTSendString(buff,4);
}

void main(void) {
	WDTCTL=WDTPW+WDTHOLD;
    BCSCTL1 = CALBC1_16MHZ;      /* Set DCO to16MHz */
    DCOCTL = CALDCO_16MHZ;
	__delay_cycles(100000);			//等待电压稳定
	 InitUART();
	TCA6416A_Init();
	Slope_Measure_Init();
	HT1621_init();
	LCD_Clear();
	Display_SLOPE();
	HT1621_Reflash(LCD_Buffer);
	//-----设定WDT为16ms定时中断-----
	WDTCTL=WDT_ADLY_16;
	//-----WDT中断使能-----
    IE1|=WDTIE;
	 _enable_interrupts();



	while(1);
}

/******************************************************************************************************
 * 名       称:WDT_ISR(void)
 * 功       能:WDT定时中断子函数
 * 入口参数:无
 * 出口参数:无
 * 说       明:直接调用事件处理函数即可
 * 范       例:无
 ******************************************************************************************************/
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
	 IE1&=~WDTIE;
	WDT_OnTime();
	 IE1|=WDTIE;
}
/******************************************************************************************************
 * 名       称:WDT_OnTime()
 * 功       能:WDT定时中断的事件处理函数
 * 入口参数:无
 * 出口参数:无
 * 说       明:主要工作都在事件处理函数中体现
 * 范       例:无
 ******************************************************************************************************/
void WDT_OnTime()
{
	static unsigned char Charge_Ready=0;			//充满电标志位
	static unsigned char REF_Mreasure_Ready=0;	//等于8表明参考电阻已测完
	static unsigned long R_REF_Sum=0;			//暂存参考电阻的累加值
		if(Charge_Ready==0)		//未充满电
		{
			Slope_Port_Charge();	//充电
			Slope_R_Dect();			//执行显示LED的任务
			Charge_Ready=1;		//充满电标志
		}
		else
		{
			//-----测量8次参考电阻值-----
			if(REF_Mreasure_Ready<8)					// 判断是否继续测量参考电阻值
			{
				Slope_Measure_REF();						//测参考电阻值
				R_REF_Sum=R_REF_Sum+R_REF;		//累加电阻值
				if(REF_Mreasure_Ready==7)	R_REF=R_REF_Sum>>3;	//测量完毕求出参考电阻的平均值
				REF_Mreasure_Ready++;					//测量次数累加
			}
			//-----得到参考电阻值后,开始不停的测量传感器电阻值-----
			else
				Slope_Measure_SENS();					//测完参考电阻才测传感器电阻
				Charge_Ready=0;							//测完一次,又该充电了
		}
}

/******************************************************************************************************
 * 名       称:Slope_R_Dect()
 * 功       能:对传感器电阻判断档位,调用LED显示程序
 * 入口参数:无
 * 出口参数:无
 * 说       明:主要工作都在事件处理函数中体现
 * 范       例:无
 ******************************************************************************************************/
void Slope_R_Dect()
{

	static unsigned int Rsens=0;
	unsigned char Key_Last=0;		//用于判断是否数据有更新
	Key_Last=Key;
	//-----通过10k参考电阻,计算电阻绝对值,单位百欧-----
	Rsens=(((unsigned long int)100)*(unsigned long int)R_SENS)/R_REF;
	//-----传感器电阻分档判断,5k至15k之间,分8档-----
	if(Rsens<=R_Class[0]) 			Key=0;
	else if (Rsens<=R_Class[1]) 	Key=1;
	else if (Rsens<=R_Class[2])	Key=2;
	else if (Rsens<=R_Class[3]) 	Key=3;
	else if (Rsens<=R_Class[4]) 	Key=4;
	else if (Rsens<=R_Class[5]) 	Key=5;
	else if (Rsens<=R_Class[6]) 	Key=6;
	else 	if(Rsens<=R_Class[7]) 	Key=7;
	else											Key=8;
	//-----调用一系列显示任务-----
	Display_RSENS(Rsens);		//显示实际电阻值
	if(!(Key==Key_Last))			//显示电阻分档值
	{
		LCD_DisplayDigit(LCD_DIGIT_CLEAR ,6);
		LCD_DisplayDigit(Key,6);
		HT1621_Reflash_Digit(6);
	}
	TCA6416A_LED(Key);		 	//LED灯柱显示
}
/******************************************************************************************************
 * 名       称:TCA6416A_LED()
 * 功       能:根据传感器电阻值,实现LED灯柱效果
 * 入口参数:无
 * 出口参数:无
 * 说       明:需要调用I2C和TCA6416控制LED
 * 范       例:无
 ******************************************************************************************************/
void TCA6416A_LED(unsigned char num)
{
	unsigned char i = 0;
	for(i=0;i<8;i++)
	{
		if(i<num)					// 判断当前需要点亮几盏灯
			PinOUT(i,0);			//根据LED接法,IO低电平为点亮LED
		else
			PinOUT(i,1);			//根据LED接法,IO高电平为熄灭LED
	}
}
/******************************************************************************************************
 * 名       称:Display_SLOPE()
 * 功       能:在LED上显示固定不变的内容
 * 入口参数:无
 * 出口参数:无
 * 说       明:包括显示SLOPE,2个小数点,logo,kΩ单位。
 * 范       例:无
 ******************************************************************************************************/
void Display_SLOPE()
{
	//-----显示S-----
	LCD_DisplayDigit(5,1);
	//-----显示L-----
	LCD_DisplayDigit(0,2);
	LCD_ClearSeg(_LCD_2A);
	LCD_ClearSeg(_LCD_2B);
	LCD_ClearSeg(_LCD_2C);
	//-----显示O-----
	LCD_DisplayDigit(0,3);
	//-----显示P-----
	LCD_DisplayDigit(8,4);
	LCD_ClearSeg(_LCD_4C);
	LCD_ClearSeg(_LCD_4D);
	//-----显示E-----
	LCD_DisplayDigit(8,5);
	LCD_ClearSeg(_LCD_5B);
	LCD_ClearSeg(_LCD_5C);
	//-----显示小数点-----
	LCD_DisplaySeg(_LCD_DOT4);
	LCD_DisplaySeg(_LCD_DOT6);
	//-----显示logo-----
	LCD_DisplaySeg(_LCD_TI_logo);
	LCD_DisplaySeg(_LCD_QDU_logo);
	//-----显示kΩ-----
	LCD_DisplaySeg(_LCD_k_OHOM);
	LCD_DisplaySeg(_LCD_OHOM);
}
/******************************************************************************************************
 * 名       称:Display_RSENS()
 * 功       能:在LED的小8字段上显示实测传感器电阻值
 * 入口参数:无
 * 出口参数:无
 * 说       明:哪位内容有改变才更新该位的显存。
 * 范       例:无
 ******************************************************************************************************/
void Display_RSENS(unsigned char Rsens)
{
	InitUART();
	unsigned char i=0;
	static unsigned char Digit[3]={0};
	unsigned char Digit_Past[3]={0};		//用于对比数值是否有改变
	for(i=0;i<3;i++){
		Digit_Past[i]=Digit[i];
	}
	//-----拆分数字-----
	Digit[2]=Rsens/100;
	Digit[1]=(Rsens%100)/10;
	Digit[0]=Rsens%10;

	//-----判别数位的改变,并更新该位显存-----
	for(i=0;i<3;i++)
	{
		if(!(Digit[i]==Digit_Past[i]))		//如果有变化
		{
			LCD_DisplayDigit(LCD_DIGIT_CLEAR ,i+8);	//清除该8字段
			LCD_DisplayDigit(Digit[i],i+8);						//写显存映射
			HT1621_Reflash_Digit(i+8);							//仅更新该8字段的显存
			UARTSendString(Digit,3);






		}
	}
}

代码中已实现将电阻值用LCD显示的功能,旋转电位器即可改变该电阻阻值,如图,只要将左上角的电阻按一定频率传输至串口调试助手即可,例如图中的9.7k欧中的9.7传输至串口调试助手,旋转电位器后又可以将新的电阻值传输至串口调试助手,请提供最终代码

  • 写回答

2条回答 默认 最新

  • soar3033 2021-06-28 12:58
    关注
    #include"MSP430G2553.h"
    #include "Slope.h"
    #include "TCA6416A.h"
    #include "HT1621.h"
    #include "LCD_128.h"
    #include "stdint.h"
    unsigned char Key = 0;		//轮盘电位器的电阻等效按键值
    //-----待测“传感器电阻”的分档值,实际接入了5k定值电阻+10k轮盘电位器-----
    const unsigned char R_Class[8] = { 55,67,82,97,113,128,138,144 };		//单位为百欧
    void WDT_OnTime();
    void Slope_R_Dect();			//测得待测电阻后的事件处理函数
    void TCA6416A_LED(unsigned char num);		//LED灯柱显示函数
    void Display_SLOPE();
    void Display_RSENS(unsigned char Rsens);
    volatile int count;
    volatile int adc_flag;
    volatile unsigned char Digits[3];
    /*
     * @fn:		void InitUART(void)
     * @brief:	初始化串口,包括设置波特率,数据位,校验位等
     * @para:	none
     * @return:	none
     * @comment:初始化串口
     */
    void InitUART(void)
    {
    	/*SMCLK时钟源为DCO*/
    	BCSCTL2 &= ~SELS;
    	/*SMCLK分频系数*/
    	BCSCTL2 &= ~(DIVS0 | DIVS1);
    	/*复位USCI_Ax*/
    	UCA0CTL1 |= UCSWRST;
    	/*选择USCI_Ax为UART模式*/
    	UCA0CTL0 &= ~UCSYNC;
    	/*配置UART时钟源为SMCLK*/
    	UCA0CTL1 |= UCSSEL1;
    	/*配置波特率为9600@1MHz*/
    	UCA0BR0 = 0x68;
    	UCA0BR1 = 0x00;
    	UCA0MCTL = 1 << 1;
    	/*使能端口复用*/
    	P1SEL |= BIT1 + BIT2;
    	P1SEL2 |= BIT1 + BIT2;
    	/*清除复位位,使能UART*/
    	UCA0CTL1 &= ~UCSWRST;
    }
    /*
     * @fn:		void UARTSendString(uint8_t *pbuff,uint8_t num)
     * @brief:	通过串口发送字符串
     * @para:	pbuff:指向要发送字符串的指针
     * 			num:要发送的字符个数
     * @return:	none
     * @comment:通过串口发送字符串
     */
    void UARTSendString(unsigned char* pbuff, uint8_t num)
    {
    	uint8_t cnt = 0;
    	for (cnt = 0; cnt < num; cnt++)
    	{
    		while (!(IFG2 & UCA0TXIFG));
    		//while (UCA0STAT & UCBUSY);
    		//__delay_cycles(5000);
    		UCA0TXBUF = *(pbuff + cnt);
    		IFG2 &= ~UCA0TXIFG;
    	}
    }
    /*
     * @fn:		void PrintNumber(uint16_t num)
     * @brief:	通过串口发送数字
     * @para:	num:变量
     * @return:	none
     * @comment:通过串口发送数字
     */
    void PrintNumber(uint16_t num)
    {
    	uint8_t buff[4] = { 0,0,0,'\n' };
    	uint8_t cnt = 0;
    	for (cnt = 0; cnt < 3; cnt++)
    	{
    		buff[2 - cnt] = (uint8_t)(num % 10 + '0');
    		num /= 10;
    	}
    	UARTSendString(buff, 4);
    }
    void main(void) {
    	count = 0;
    	adc_flag = 0;
    	WDTCTL = WDTPW + WDTHOLD;
    	BCSCTL1 = CALBC1_16MHZ;      /* Set DCO to16MHz */
    	DCOCTL = CALDCO_16MHZ;
    	__delay_cycles(100000);			//等待电压稳定
    	InitUART();
    	TCA6416A_Init();
    	Slope_Measure_Init();
    	HT1621_init();
    	LCD_Clear();
    	Display_SLOPE();
    	HT1621_Reflash(LCD_Buffer);
    	//-----设定WDT为16ms定时中断-----
    	WDTCTL = WDT_ADLY_16;
    	//-----WDT中断使能-----
    	IE1 |= WDTIE;
    	_enable_interrupts();
    
    	while (1) {
    		if (adc_flag == 1) {
    			adc_flag = 0;
    			Digits[0] = 15;
    			Digits[1] = 16;
    			Digits[2] = 17;
    			//UARTSendString((uint8_t*)Digits, 3);
    			UCA0TXBUF = Digits[0];
    
    			UCA0TXBUF = Digits[1];
    			UCA0TXBUF = Digits[2];
    		}
    	}
    }
    /******************************************************************************************************
     * 名       称:WDT_ISR(void)
     * 功       能:WDT定时中断子函数
     * 入口参数:无
     * 出口参数:无
     * 说       明:直接调用事件处理函数即可
     * 范       例:无
     ******************************************************************************************************/
    #pragma vector=WDT_VECTOR
    __interrupt void WDT_ISR(void)
    {
    	IE1 &= ~WDTIE;
    	
    	IE1 |= WDTIE;
    	count++;
    	if (count>6)
    	{
    		count = 0;
    		adc_flag = 1;
    	}
    	WDT_OnTime();
    }
    /******************************************************************************************************
     * 名       称:WDT_OnTime()
     * 功       能:WDT定时中断的事件处理函数
     * 入口参数:无
     * 出口参数:无
     * 说       明:主要工作都在事件处理函数中体现
     * 范       例:无
     ******************************************************************************************************/
    void WDT_OnTime()
    {
    	static unsigned char Charge_Ready = 0;			//充满电标志位
    	static unsigned char REF_Mreasure_Ready = 0;	//等于8表明参考电阻已测完
    	static unsigned long R_REF_Sum = 0;			//暂存参考电阻的累加值
    	if (Charge_Ready == 0)		//未充满电
    	{
    		Slope_Port_Charge();	//充电
    		Slope_R_Dect();			//执行显示LED的任务
    		Charge_Ready = 1;		//充满电标志
    	}
    	else
    	{
    		//-----测量8次参考电阻值-----
    		if (REF_Mreasure_Ready < 8)					// 判断是否继续测量参考电阻值
    		{
    			Slope_Measure_REF();						//测参考电阻值
    			R_REF_Sum = R_REF_Sum + R_REF;		//累加电阻值
    			if (REF_Mreasure_Ready == 7)	R_REF = R_REF_Sum >> 3;	//测量完毕求出参考电阻的平均值
    			REF_Mreasure_Ready++;					//测量次数累加
    		}
    		//-----得到参考电阻值后,开始不停的测量传感器电阻值-----
    		else
    			Slope_Measure_SENS();					//测完参考电阻才测传感器电阻
    		Charge_Ready = 0;							//测完一次,又该充电了
    	}
    }
    /******************************************************************************************************
     * 名       称:Slope_R_Dect()
     * 功       能:对传感器电阻判断档位,调用LED显示程序
     * 入口参数:无
     * 出口参数:无
     * 说       明:主要工作都在事件处理函数中体现
     * 范       例:无
     ******************************************************************************************************/
    void Slope_R_Dect()
    {
    	static unsigned int Rsens = 0;
    	unsigned char Key_Last = 0;		//用于判断是否数据有更新
    	Key_Last = Key;
    	//-----通过10k参考电阻,计算电阻绝对值,单位百欧-----
    	Rsens = (((unsigned long int)100) * (unsigned long int)R_SENS) / R_REF;
    	//-----传感器电阻分档判断,5k至15k之间,分8档-----
    	if (Rsens <= R_Class[0]) 			Key = 0;
    	else if (Rsens <= R_Class[1]) 	Key = 1;
    	else if (Rsens <= R_Class[2])	Key = 2;
    	else if (Rsens <= R_Class[3]) 	Key = 3;
    	else if (Rsens <= R_Class[4]) 	Key = 4;
    	else if (Rsens <= R_Class[5]) 	Key = 5;
    	else if (Rsens <= R_Class[6]) 	Key = 6;
    	else 	if (Rsens <= R_Class[7]) 	Key = 7;
    	else											Key = 8;
    	//-----调用一系列显示任务-----
    	Display_RSENS(Rsens);		//显示实际电阻值
    	if (!(Key == Key_Last))			//显示电阻分档值
    	{
    		LCD_DisplayDigit(LCD_DIGIT_CLEAR, 6);
    		LCD_DisplayDigit(Key, 6);
    		HT1621_Reflash_Digit(6);
    	}
    	TCA6416A_LED(Key);		 	//LED灯柱显示
    }
    /******************************************************************************************************
     * 名       称:TCA6416A_LED()
     * 功       能:根据传感器电阻值,实现LED灯柱效果
     * 入口参数:无
     * 出口参数:无
     * 说       明:需要调用I2C和TCA6416控制LED
     * 范       例:无
     ******************************************************************************************************/
    void TCA6416A_LED(unsigned char num)
    {
    	unsigned char i = 0;
    	for (i = 0; i < 8; i++)
    	{
    		if (i < num)					// 判断当前需要点亮几盏灯
    			PinOUT(i, 0);			//根据LED接法,IO低电平为点亮LED
    		else
    			PinOUT(i, 1);			//根据LED接法,IO高电平为熄灭LED
    	}
    }
    /******************************************************************************************************
     * 名       称:Display_SLOPE()
     * 功       能:在LED上显示固定不变的内容
     * 入口参数:无
     * 出口参数:无
     * 说       明:包括显示SLOPE,2个小数点,logo,kΩ单位。
     * 范       例:无
     ******************************************************************************************************/
    void Display_SLOPE()
    {
    	//-----显示S-----
    	LCD_DisplayDigit(5, 1);
    	//-----显示L-----
    	LCD_DisplayDigit(0, 2);
    	LCD_ClearSeg(_LCD_2A);
    	LCD_ClearSeg(_LCD_2B);
    	LCD_ClearSeg(_LCD_2C);
    	//-----显示O-----
    	LCD_DisplayDigit(0, 3);
    	//-----显示P-----
    	LCD_DisplayDigit(8, 4);
    	LCD_ClearSeg(_LCD_4C);
    	LCD_ClearSeg(_LCD_4D);
    	//-----显示E-----
    	LCD_DisplayDigit(8, 5);
    	LCD_ClearSeg(_LCD_5B);
    	LCD_ClearSeg(_LCD_5C);
    	//-----显示小数点-----
    	LCD_DisplaySeg(_LCD_DOT4);
    	LCD_DisplaySeg(_LCD_DOT6);
    	//-----显示logo-----
    	LCD_DisplaySeg(_LCD_TI_logo);
    	LCD_DisplaySeg(_LCD_QDU_logo);
    	//-----显示kΩ-----
    	LCD_DisplaySeg(_LCD_k_OHOM);
    	LCD_DisplaySeg(_LCD_OHOM);
    }
    /******************************************************************************************************
     * 名       称:Display_RSENS()
     * 功       能:在LED的小8字段上显示实测传感器电阻值
     * 入口参数:无
     * 出口参数:无
     * 说       明:哪位内容有改变才更新该位的显存。
     * 范       例:无
     ******************************************************************************************************/
    void Display_RSENS(unsigned char Rsens)
    {
    	InitUART();
    	unsigned char i = 0;
    	static unsigned char Digit[3] = { 0 };
    	unsigned char Digit_Past[3] = { 0 };		//用于对比数值是否有改变
    	for (i = 0; i < 3; i++) {
    		Digit_Past[i] = Digit[i];
    	}
    	//-----拆分数字-----
    	Digit[2] = Rsens / 100;
    	Digit[1] = (Rsens % 100) / 10;
    	Digit[0] = Rsens % 10;
    	Digits[2] = Digit[2];
    	Digits[1] = Digit[1];
    	Digits[0] = Digit[0];
    	//-----判别数位的改变,并更新该位显存-----
    	for (i = 0; i < 3; i++)
    	{
    		if (!(Digit[i] == Digit_Past[i]))		//如果有变化
    		{
    			LCD_DisplayDigit(LCD_DIGIT_CLEAR, i + 8);	//清除该8字段
    			LCD_DisplayDigit(Digit[i], i + 8);						//写显存映射
    			HT1621_Reflash_Digit(i + 8);							//仅更新该8字段的显存
    			
    
    
    
    		}
    	}
    	
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题