佛山网站优化建设,微信公众号是在哪个网站做的,做网站毕设答辩问题,外贸工厂的网站建设文章目录MSP430一、GPIO二、点亮LED三、按键控制LED四、更改主时钟五、串口通信六、串口中断七、外部中断八、定时器九、定时器中断十、PWM十一、ADCMSP430
MSP430 是德州仪器#xff08;TI#xff09;一款性能卓越的超低功耗 16 位单片机#xff0c;自问世以来#xff0c…
文章目录MSP430一、GPIO二、点亮LED三、按键控制LED四、更改主时钟五、串口通信六、串口中断七、外部中断八、定时器九、定时器中断十、PWM十一、ADCMSP430
MSP430 是德州仪器TI一款性能卓越的超低功耗 16 位单片机自问世以来MSP430 单片机一直是业内公认的功耗最低的单片机。除采用先进的制造工艺使芯片的静态电流尽可能降低外MSP430 的独立可配置的时钟系统是其低功耗的基石之一。在追求绿色能源的今天MSP430 超低功耗微控制器正以其超低功耗的特性以及丰富多样化的外设受到越来越多设计者们的青睐。
一、GPIO MSP430G2553共有两个通用数字端口P1和P2。
端口P1和 P2具有输入/输出\中断和外部模块功能这些功能可以通过它们各自的7个控制寄存器的设置来实现。
1. PxDIR输入/输出方向寄存器
相互独立的8位分别定义了8个引脚的输入/输出方向.8位在PUC后都被复位。使用时先根据需要定义端口的方向以满足设计者要求。 0 : I/O引脚被切换成输入模式; 1 : IO引脚被切换成输出模式。
2. PxIN输入寄存器
输入寄存器是CPU扫描IO引脚信号的只读寄存器。通过读取该寄存器的内容获取IO端口的输入信号。此时引脚的方向必须选定为输入。读出时该引脚的方向寄存器必须设置为输入模式。
3. PxOUT输出寄存器
该寄存器为IO端口的输出缓冲寄存器。其内容可以像操作内存数据一样写入以达到改变IO口状态的目的。在读取时输出缓存的内容与引脚方向定义无关。改变方向寄存器的内容输出缓存的内容不受影响。
4. PxIE中断使能寄存器
该寄存器的各引脚都有一位用以控制该引脚是否允许中断该寄存器中0 :禁止该位中断; 1 :允许该位中断。
5. PxIES 中断触发沿选择寄存器
如果允许Px口的某个引脚中断还需定义该引脚的中断触发沿。该寄存器的8位分别定义了Px口的8个引脚的中断触发沿。 0:上升沿使相应标志置位; 1:下降沿使相应标志置位。
6. PxIFG中断标志寄存器
该寄存器有8个标志位它们含有相应引脚是否有待处理中断的信息即 相应引脚是否有中断请求。如果Px的某个引脚允许中断同时选择上升沿则当该引脚发生由低电平向高电平跳变时PxFG的相应位就会置位表明在该引脚上有中断事件发生。 0 :没有中断请求;1 :有中断请求。
7. PxSEL功能选择寄存器
Pl和P2两端口还有其他片内外设功能考虑减少引脚将这些功能与芯片外的联系通过复用P1和P2引脚的方式来实现.PxSEL用来选择引脚的IO端口功能与外围模块功能。 0 :选择引脚为I/O端口; 1 :选择引脚为外围模块功能。 以下我以msp430g2553为例解析GPIO的使用。 二、点亮LED 由上方电路图可读
LED灯为P1.0和P1.6引脚与下方GND相连则为高电平驱动。按键为P1.3引脚默认为悬空状态当按键按下时与GND相连为低电平状态。
#include msp430.h int main(void)
{WDTCTL WDTPW | WDTHOLD; // 关闭看门狗/*初始化LED2为输出*/P1DIR | BIT6;/*初始化LED2为低电平熄灭*/P1OUT ~BIT6;/*初始化KEY P1.3为输入*/P1DIR ~BIT3;/*使能P1.3口的上拉电阻*/P1REN | BIT3;P1OUT | BIT3;while(1){if(P1IN BIT3) /*如果P1.3口为高电平证明按键没有被按下*/{P1OUT ~BIT6; //熄灭LED2}else{P1OUT | BIT6; //点亮LED2}}return 0;
}
三、按键控制LED
#include msp430.h int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*初始化LED2为输出*/P1DIR | BIT6;/*初始化LED2为低电平熄灭*/P1OUT ~BIT6;/*初始化KEY P1.3为输入*/P1DIR ~BIT3;/*使能P1.3口的上拉电阻*/P1REN | BIT3;P1OUT | BIT3;while(1){if(P1IN BIT3) /*如果P1.3口为高电平证明按键没有被按下*/{P1OUT ~BIT6; //熄灭LED2}else{P1OUT | BIT6; //点亮LED2}}return 0;
}四、更改主时钟
#include msp430.h int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*设置MCLK频率1,8,12,16*/DCOCTL CALDCO_16MHZ;BCSCTL1 CALBC1_16MHZ;/*初始化LED2所在的IO口P1.6设置为输出*/P1DIR | BIT6;/*初始化LED2 为低电平*/P1OUT ~BIT6;while(1){P1OUT ^ BIT6;__delay_cycles(500000);}return 0;
}五、串口通信 #include msp430.h
#include stdint.h
/** fn: void InitSystemClock(void)* brief: 初始化系统时钟* para: none* return:none* comment: 初始化系统时钟*/
void InitSystemClock(void)
{/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;/*配置SMCLK的时钟源为DCO*/BCSCTL2 ~SELS;/*SMCLK的分频系数置为1*/BCSCTL2 ~(DIVS0 | DIVS1);
}/** fn: void InitUART(void)* brief: 初始化串口包括设置波特率数据位校验位等* para: none* return:none* comment: 初始化串口*/
void InitUART(void)
{/*复位USCI_Ax*/UCA0CTL1 | UCSWRST;/*设置为异步模式*/UCA0CTL0 ~UCSYNC;/*配置UART时钟源为SMCLK*/UCA0CTL1 | UCSSEL1;/*配置波特率为9600*/UCA0BR0 0x68;UCA0BR1 0x00;UCA0MCTL 1 1;/*配置端口,使能端口复用*/P1SEL | BIT1 BIT2;P1SEL2 | BIT1 BIT2;/*清除复位位使能UART*/UCA0CTL1 ~UCSWRST;
}/** fn: void UARTSendString(uint8_t *pbuff, uint_8 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);UCA0TXBUF *(pbuff cnt);}
}/** fn: void PrintNumber(uint16_t num)* brief: 初始化串口发送数字* para: num变量* return:none* comment: 初始化串口发送数字*/
void PrintNumber(uint16_t num)
{uint8_t cnt 0;uint8_t buff[6] {0,0,0,0,0,\n};for(cnt 0; cnt 5; cnt){buff[4 - cnt] (uint8_t)(num % 10 0);num / 10;}UARTSendString(buff,6);
}int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timerInitSystemClock();InitUART();while(1){PrintNumber(23456);__delay_cycles(500000);}return 0;
}六、串口中断
#include msp430.h
#include stdint.huint8_t combuff[20] {0}; //长度为20的命令缓冲区用于保存串口接收到的命令
uint8_t iscomend 0; //命令结束标志位
/** fn: void InitSystemClock(void)* brief: 初始化系统时钟* para: none* return:none* comment: 初始化系统时钟*/
void InitSystemClock(void)
{/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;/*配置SMCLK的时钟源为DCO*/BCSCTL2 ~SELS;/*SMCLK的分频系数置为1*/BCSCTL2 ~(DIVS0 | DIVS1);
}/** fn: void InitUART(void)* brief: 初始化串口包括设置波特率数据位校验位等* para: none* return:none* comment: 初始化串口*/
void InitUART(void)
{/*复位USCI_Ax*/UCA0CTL1 | UCSWRST;/*设置为异步模式*/UCA0CTL0 ~UCSYNC;/*配置UART时钟源为SMCLK*/UCA0CTL1 | UCSSEL1;/*配置波特率为9600*/UCA0BR0 0x68;UCA0BR1 0x00;UCA0MCTL 1 1;/*配置端口,使能端口复用*/P1SEL | BIT1 BIT2;P1SEL2 | BIT1 BIT2;/*清除复位位使能UART*/UCA0CTL1 ~UCSWRST;/*接收中断启用*/IE2 | UCA0RXIE;/*清空接收中断标志*/IFG2 ~UCA0RXIFG;
}/** fn: void UARTSendString(uint8_t *pbuff, uint_8 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);UCA0TXBUF *(pbuff cnt);}
}/** fn: void PrintNumber(uint16_t num)* brief: 初始化串口发送数字* para: num变量* return:none* comment: 初始化串口发送数字*/
void PrintNumber(uint16_t num)
{uint8_t cnt 0;uint8_t buff[6] {0,0,0,0,0,\n};for(cnt 0; cnt 5; cnt){buff[4 - cnt] (uint8_t)(num % 10 0);num / 10;}UARTSendString(buff,6);
}/** fn: void Execute(uint8_t *combuff)* brief: 串口命令执行函数* para: combuff指向串口命令缓冲区的指针* return:none* comment: 串口命令执行函数*/
void Execute(uint8_t *combuff)
{const uint8_t charbuff[5][10] {王龙,米雷龙,班长,LED1 ON!,LED1 OFF!};if(combuff[0] charbuff[0][0] combuff[1] charbuff[0][1]){UARTSendString(aa,2);}else if(combuff[0] charbuff[1][0] combuff[1] charbuff[1][1]){UARTSendString(bb,2);}else if(combuff[0] charbuff[2][0] combuff[1] charbuff[2][1]){UARTSendString(cc,2);}else if(combuff[0] charbuff[3][0] combuff[6] charbuff[3][6]){UARTSendString(Yes,LED ON!,11);P1OUT | BIT0;}if(combuff[0] charbuff[4][0] combuff[6] charbuff[4][6]){UARTSendString(Yes,LED OFF!,12);P1OUT ~BIT0;}
}int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timerInitSystemClock();InitUART();P1DIR | BIT0;P1OUT ~BIT0;__bis_SR_register(GIE);//打开总中断while(1){if(iscomend){iscomend 0; //清除标志位防止重复执行Execute(combuff);}}return 0;
}#pragma vector USCIAB0RX_VECTOR
__interrupt void UART_Receive_ISR(void) //Port1_ISR(void) 中断服务函数
{static uint8_t cnt 0;if(IFG2 UCA0RXIFG)//检测是否是USCI_AO的接收中断USCI_AO和USCI_BO的接收中断共享同一向量{IFG2 ~UCA0RXIFG; //清空接收中断标志combuff[cnt] UCA0RXBUF; //保存命令cnt % 20; //防止cnt大于20导致缓存区溢出if(combuff[cnt - 1] \n){cnt 0; //复位计数器iscomend 1; //命令接收完毕标志}}/*清空接收中断标志*/IFG2 ~UCA0RXIFG;
}
七、外部中断
#include msp430.h /*** main.c*/
int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*初始化LED2为输出*/P1DIR | BIT6;/*初始化LED2为低电平熄灭*/P1OUT ~BIT6;/*初始化KEY P1.3为输入*/P1DIR ~BIT3;/*使能P1.3口的上拉电阻*/P1REN | BIT3;P1OUT | BIT3;/*打开P1.3口的中断*/P1IE | BIT3;/*设定为下降沿触发*/P1IES | BIT3;/*清除中断标志位*/P1IFG ~BIT3;/*打开全局中断*/__bis_SR_register(GIE);while(1){}return 0;
}#pragma vector PORT1_VECTOR
__interrupt void Port1_ISR(void) //Port1_ISR(void) 中断服务函数
{if(P1IFG BIT3) //判断是否P1.3产生中断{P1OUT ^ BIT6;P1IFG ~ BIT3; //清除标志位}
}八、定时器 #include msp430.h
#include stdint.hint main(void)
{uint8_t cnt 0;WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;P1DIR | BIT0 ;/*配置时钟源为SMCLK*/TA1CTL | TASSEL_2;/*设置工作模式为Up Mode*/TA1CTL | MC_1;/*设置定时时间间隔*/TA1CCR0 49999; //0.05swhile(1){if(TA1CTL TAIFG){cnt;TA1CTL ~TAIFG; //清除标志位if(cnt 20){P1OUT ^ BIT0;cnt 0;}}}return 0;
}九、定时器中断
#include msp430.h
#include stdint.huint32_t currenttime 40500; //用来保存时间的变量初值代表11:15:00
uint8_t flag 0;
/** fn: void InitSystemClock(void)* brief: 初始化系统时钟* para: none* return:none* comment: 初始化系统时钟*/
void InitSystemClock(void)
{/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;/*配置SMCLK的时钟源为DCO*/BCSCTL2 ~SELS;/*SMCLK的分频系数置为1*/BCSCTL2 ~(DIVS0 | DIVS1);
}/** fn: void InitUART(void)* brief: 初始化串口包括设置波特率数据位校验位等* para: none* return:none* comment: 初始化串口*/
void InitUART(void)
{/*复位USCI_Ax*/UCA0CTL1 | UCSWRST;/*设置为异步模式*/UCA0CTL0 ~UCSYNC;/*配置UART时钟源为SMCLK*/UCA0CTL1 | UCSSEL1;/*配置波特率为9600*/UCA0BR0 0x68;UCA0BR1 0x00;UCA0MCTL 1 1;/*配置端口,使能端口复用*/P1SEL | BIT1 BIT2;P1SEL2 | BIT1 BIT2;/*清除复位位使能UART*/UCA0CTL1 ~UCSWRST;/*接收中断启用*/IE2 | UCA0RXIE;/*清空接收中断标志*/IFG2 ~UCA0RXIFG;
}/** fn: void UARTSendString(uint8_t *pbuff, uint_8 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);UCA0TXBUF *(pbuff cnt);}
}/** fn: void PrintTime(uint32_t time)* brief: 初始化串口发送字符串* para: pbuff:指向要发送字符串的指针* num:要发送的字符个数* return:none* comment: 初始化串口发送字符串*/
void PrintTime(uint32_t time)
{uint8_t charbuff[] {0,0,:,0,0,:,0,0,\n};charbuff[7] (uint8_t)((time % 60) % 10) 0; //得到当前秒个位charbuff[6] (uint8_t)((time % 60) / 10) 0; //得到当前秒十位charbuff[4] (uint8_t)((time % 3600) / 60 % 10) 0; //得到当前分个位charbuff[3] (uint8_t)((time % 3600) / 60 / 10) 0; //得到当前分十位charbuff[1] (uint8_t)((time / 3600) % 10) 0; //得到当前时个位charbuff[0] (uint8_t)(time / 3600 / 10) 0; //得到当前时十位UARTSendString(当前时间,10);UARTSendString(charbuff,9);
}int main(void)
{WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;InitSystemClock();InitUART();P1DIR | BIT0 ;/*配置时钟源为SMCLK*/TA1CTL | TASSEL_2;/*设置工作模式为Up Mode*/TA1CTL | MC_1;/*设置定时时间间隔*/TA1CCR0 49999; //0.05s/*打开定时器TAIFG中断*/TA1CTL | TAIE;/*打开全局中断*/__bis_SR_register(GIE);while(1){if(flag 1){flag 0;P1OUT ^ BIT0;PrintTime(currenttime);}}return 0;
}#pragma vector TIMER1_A1_VECTOR
__interrupt void Timer_Tick(void)
{static uint8_t cnt 0;switch(TA1IV) //读取的话无需手动清零标志位{case 0x02:break;case 0x04:break;case 0x0A:cnt;if(cnt 20){cnt 0;flag 1; //1s时间到了currenttime ; //时间加1currenttime % 86400; //一天24小时防止溢出}break;default:break;}
}
十、PWM
#include msp430.h int main(void)
{unsigned int cnt 0;WDTCTL WDTPW | WDTHOLD; // stop watchdog timer/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;/*初始化P1.6为输入*/P1DIR ~BIT6;/*设置时钟源为SMCLK*/TA1CTL | TASSEL_2;/*设置工作模式为Up Dowm*/TA1CTL | MC_0 | MC_1;/*设置TA1CCR0为0x00ff*/TA1CCR0 0x00FF;/*设置TA1CCR2为0x00ff*/TA1CCR2 0x00FF; //占空比 TACCR0 - TACCR2/ TACCR0 频率 SMCLK / (TACCR01)/2/*设置为比较模式*/TA1CCTL0 ~CAP;TA1CCTL2 ~CAP;/*设置比较输出模式*/TA1CCTL2 | OUTMOD_6;/*设置IO复用*/P2SEL | BIT5;P2DIR | BIT5;while(1){for(cnt 0;cnt 0x00FF; cnt){TA1CCR2 cnt;__delay_cycles(5000);}for(cnt 0x00FF;cnt 0; cnt--){TA1CCR2 cnt;__delay_cycles(5000);}}return 0;
}十一、ADC #include msp430.h
#include stdint.h/** fn: void InitSystemClock(void)* brief: 初始化系统时钟* para: none* return:none* comment: 初始化系统时钟*/
void InitSystemClock(void)
{/*配置DCO为1MHZ时钟*/DCOCTL CALDCO_1MHZ;BCSCTL1 CALBC1_1MHZ;/*配置SMCLK的时钟源为DCO*/BCSCTL2 ~SELS;/*SMCLK的分频系数置为1*/BCSCTL2 ~(DIVS0 | DIVS1);
}/** fn: void InitUART(void)* brief: 初始化串口包括设置波特率数据位校验位等* para: none* return:none* comment: 初始化串口*/
void InitUART(void)
{/*复位USCI_Ax*/UCA0CTL1 | UCSWRST;/*设置为异步模式*/UCA0CTL0 ~UCSYNC;/*配置UART时钟源为SMCLK*/UCA0CTL1 | UCSSEL1;/*配置波特率为9600*/UCA0BR0 0x68;UCA0BR1 0x00;UCA0MCTL 1 1;/*配置端口,使能端口复用*/P1SEL | BIT1 BIT2;P1SEL2 | BIT1 BIT2;/*清除复位位使能UART*/UCA0CTL1 ~UCSWRST;/*接收中断启用*/IE2 | UCA0RXIE;/*清空接收中断标志*/IFG2 ~UCA0RXIFG;
}/** fn: void UARTSendString(uint8_t *pbuff, uint_8 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);UCA0TXBUF *(pbuff cnt);}
}/** fn: void PrintNumber(uint16_t num)* brief: 初始化串口发送数字* para: num变量* return:none* comment: 初始化串口发送数字*/
void PrintNumber(uint16_t num)
{uint8_t cnt 0;uint8_t buff[6] {0,0,0,0,0,\n};for(cnt 0; cnt 5; cnt){buff[4 - cnt] (uint8_t)(num % 10 0);num / 10;}UARTSendString(buff,6);
}/** fn: void PrintFloat(float num)* brief: 初始化串口发送浮点型数字* para: num浮点型变量* return:none* comment: 初始化串口发送浮点型数字*/
void PrintFloat(float num)
{uint8_t buff[] {0,.,0,0,0,\n};uint16_t temp (uint16_t)(num * 1000);buff[0] (uint8_t)(temp / 1000) 0;buff[2] (uint8_t)((temp % 1000) / 100) 0;buff[3] (uint8_t)((temp / 100) / 10) 0;buff[4] (uint8_t)(temp % 10) 0;UARTSendString(buff,6);
}/** fn: void InitADC(void)* brief: ADC初始化* para: none* return:none* comment: ADC初始化*/
void InitADC(void)
{/*设置ADC时钟MCLK*/ADC10CTL1 | ADC10SSEL_2;/*ADC 2分频*/ADC10CTL1 | ADC10DIV_0;/*设置ADC基准源*/ADC10CTL0 | SREF_1;/*设置ADC采样保持时间64CLK*/ADC10CTL0 | ADC10SHT_3;/*设置ADC采样率200k*/ADC10CTL0 ~ADC10SR;/*ADC基准选择2.5V*/ /* ADC基准选择1.5V */ADC10CTL0 | REF2_5V; /* ADC10CTL0 ~REF2_5V; *//*开启基准*/ADC10CTL0 | REFON;/*选择ADC输入通道A0*/ADC10CTL1 | INCH_0;/*允许A0模拟输入*/ADC10AE0 | 0x0001;/*开启ADC*/ADC10CTL0 | ADC10ON;
}/** fn: uint16_t GetADCValue(void)* brief: 进行一次ADC转换并返回ADC转换结果* para: none* return:ADC转换结果* comment: ADC转换结果为10bit以uint16_t类型返回低10位有效数据*/
uint16_t GetADCValue(void)
{/*开始转换*/ADC10CTL0 | ADC10SC|ENC;/*等待转换完成*/while(ADC10CTL1 ADC10BUSY);/*返回结果*/return ADC10MEM;
}int main(void)
{float voltage 0.0;uint16_t adcvalue 0;WDTCTL WDTPW | WDTHOLD; // stop watchdog timerInitSystemClock();InitUART();InitADC();while(1){adcvalue GetADCValue();voltage adcvalue * 2.5 / 1023;UARTSendString(ADC10转接结果为,17);PrintNumber(adcvalue);UARTSendString(相应电压值为,14);PrintFloat(voltage);__delay_cycles(300000);}return 0;
}