2024-09-01
售卖作品
00

目录

功能
部分代码
全部代码

功能

MSP430G2553 单片机口袋板,流速,流量,检测与显示

部分代码

cpp
/*警告:由于G2 LaunchPad上的LED2使用了P1.6(I2C引脚),所以所有涉及到I2C的实验都必须把P1.6跳线拔除,包含本例程! * main.c */ #include"MSP430G2553.h" #include "Slope.h" #include "TCA6416A.h" #include "HT1621.h" #include "LCD_128.h" #define CPU_F ( (double) 16000000) #define delay_us( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000000.0) ) #define delay_ms( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000.0) ) #define u8 unsigned char #define u16 unsigned int #define u32 unsigned long unsigned int Rsens = 0; //最后电阻值 int xianshi_choose = 0; u32 leijiliang = 0; u32 liusu = 0; void WDT_OnTime(); void Slope_R_Dect(); //测得待测电阻后的事件处理函数 /* 显示一个数字 */ void dis_num_6( u32 num) { unsigned char bua; bua = num % 1000000 / 100000; LCD_DisplayDigit(bua, 1); bua = num % 100000 / 10000; LCD_DisplayDigit(bua, 2); bua = num % 10000 / 1000; LCD_DisplayDigit(bua, 3); bua = num % 1000 / 100; LCD_DisplayDigit(bua, 4); bua = num % 100 / 10; LCD_DisplayDigit(bua, 5); bua = num % 10; LCD_DisplayDigit(bua, 6); //LCD_DisplaySeg(i); LCD_DisplaySeg(_LCD_DOT4); HT1621_Reflash(LCD_Buffer); } /* 检测按键函数 */ void I2C_IODect() /* 检测事件确实发生了 */ { static unsigned char KEY_Past = 0, KEY_Now = 0; KEY_Past = KEY_Now; /* ----判断I2C_IO10所连的KEY1按键是否被按下------ */ if ((TCA6416A_InputBuffer & BIT8) == BIT8) KEY_Now |= BIT0; else KEY_Now &= ~BIT0; if (((KEY_Past & BIT0) == BIT0) && (KEY_Now & BIT0) != BIT0) { /*按键1 事件 */ xianshi_choose = 0; //改变xianshi_choose变量 主程序里 显示会切换 } /* ----判断I2C_IO11所连的KEY2按键是否被按下------ */ if ((TCA6416A_InputBuffer & BIT9) == BIT9) KEY_Now |= BIT1; else KEY_Now &= ~BIT1; if (((KEY_Past & BIT1) == BIT1) && (KEY_Now & BIT1) != BIT1) { /*按键2 事件 */ xianshi_choose = 1; } /* ----判断I2C_IO12所连的KEY3按键是否被按下------ */ if ((TCA6416A_InputBuffer & BITA) == BITA) KEY_Now |= BIT2; else KEY_Now &= ~BIT2; if (((KEY_Past & BIT2) == BIT2) && (KEY_Now & BIT2) == 0) { /*按键3 事件 */ } /* ----判断I2C_IO13所连的KEY4按键是否被按下------ */ if ((TCA6416A_InputBuffer & BITB) == BITB) KEY_Now |= BIT3; else KEY_Now &= ~BIT3; if (((KEY_Past & BIT3) == BIT3) && (KEY_Now & BIT3) == 0) { /*按键4 事件 */ } } //串口发送单一字符 void sendan(unsigned char zifu) { while (!(IFG2 & UCA0TXIFG)) ; // USCI_A0 TX buffer ready? UCA0TXBUF = zifu; // TX -> RXed character } //串口发送字符串 void send_string(unsigned char *s) { while ((*s) != '\0') { sendan(*s); s++; } } //串口发送流量或者累积量 void send_liuliang_andleiji() { unsigned char bua; unsigned char zifuchuan[30]; unsigned char countaa = 0; zifuchuan[countaa++] = liusu % 1000000 / 100000 + '0'; zifuchuan[countaa++] = liusu % 100000 / 10000 + '0'; zifuchuan[countaa++] = liusu % 10000 / 1000 + '0'; zifuchuan[countaa++] = liusu % 1000 / 100 + '0'; zifuchuan[countaa++] = liusu % 100 / 10 + '0'; zifuchuan[countaa++] = '.'; zifuchuan[countaa++] = liusu % 10 + '0'; zifuchuan[countaa++] = 'L'; zifuchuan[countaa++] = '/'; zifuchuan[countaa++] = 'S'; zifuchuan[countaa++] = ' '; zifuchuan[countaa++] = ' '; zifuchuan[countaa++] = leijiliang % 1000000 / 100000 + '0'; zifuchuan[countaa++] = leijiliang % 100000 / 10000 + '0'; zifuchuan[countaa++] = leijiliang % 10000 / 1000 + '0'; zifuchuan[countaa++] = leijiliang % 1000 / 100 + '0'; zifuchuan[countaa++] = leijiliang % 100 / 10 + '0'; zifuchuan[countaa++] = '.'; zifuchuan[countaa++] = leijiliang % 10 + '0'; zifuchuan[countaa++] = 'L'; send_string(zifuchuan); send_string("\r\n"); } void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_16MHZ; /* Set DCO to16MHz */ DCOCTL = CALDCO_16MHZ; __delay_cycles(100000); //等待电压稳定 TCA6416A_Init(); Slope_Measure_Init(); HT1621_init(); /* ----提示初始化成功---- */ PinOUT(0, 1); /* 指定0号管脚输出为0 */ PinOUT(1, 1); /* 指定1号管脚输出为0 */ PinOUT(2, 1); /* 指定0号管脚输出为0 */ PinOUT(3, 1); /* 指定1号管脚输出为0 */ PinOUT(4, 1); /* 指定0号管脚输出为0 */ PinOUT(5, 1); /* 指定1号管脚输出为0 */ PinOUT(6, 1); /* 指定0号管脚输出为0 */ PinOUT(7, 1); /* 指定1号管脚输出为0 */ LCD_Clear(); //-----设定WDT为16ms定时中断----- WDTCTL = WDT_ADLY_16; //-----WDT中断使能----- IE1 |= WDTIE; TA1CCTL0 = CCIE; TA1CCR0 = 3276 / 5; /* 20MS */ TA1CTL = TASSEL_1 + MC_1; //up to CCR0 //串口设置 // P1DIR |= BIT2; // P1SEL = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD // P1SEL2 = BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD // UCA0CTL1 |= UCSSEL_1; // CLK = ACLK // UCA0BR0 = 0x03; // 32kHz/9600 = 3.41 // UCA0BR1 = 0x00; // // UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3 // UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** //IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt _enable_interrupts(); while (1) { PinIN(); I2C_IODect(); /*按键检测处理 */ TA1CTL = TASSEL_1 + MC_1 + TACLR; /* 打开定时器 */ LPM0; } } // Echo back RXed character, confirm TX buffer is ready first #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { while (!(IFG2 & UCA0TXIFG)) ; // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // TX -> RXed character } /* Timer A0 interrupt service routine */ #pragma vector=TIMER1_A0_VECTOR __interrupt void Timer1_A(void) { //更新流速和累积量 每一秒钟来一次 static float bufa; static unsigned char countasdf = 0; countasdf++; if (countasdf == 50) { countasdf=0; if (Rsens != 0) { bufa = (float) Rsens * 2.2; //Rsens是拨码电阻值 2.2是系数 随便设置的 主要是得到流速 } liusu = bufa * 10; //因为要保留1位小数 乘以10 显示到LED后有小数 leijiliang += liusu; //每一秒的流速单位就是 L/S 一秒算多少升 加到累积量上 if (leijiliang > 100000) { leijiliang = 0; } if (xianshi_choose == 0) { //xianshi_choose=0 显示流速 否则显示累积量 dis_num_6(liusu); } else { dis_num_6(leijiliang); } //send_liuliang_andleiji();//串口发送流量和累积量 } TA1CTL = TASSEL_1 + MC_0 + TACLR; /* 停下时钟 */ LPM0_EXIT; } /****************************************************************************************************** * 名 称: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() { //-----通过10k参考电阻,计算电阻绝对值,单位百欧----- Rsens = (((unsigned long int) 100) * (unsigned long int) R_SENS) / R_REF; //Rsens是最后电阻值 }

全部代码

image.png

cpp
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!