msp430串口1收发程序
MSP430串口
你参考一下别人的代码看看注释很详细#include <msp430x14x.h>unsigned char RxData;//全局变量,保存接收到的数据。
void BasicClockSet(){/*下面将片外高速晶体设为MCLK分四步:(1) 起动高晶体(2) 清除OFIFG 标志位(3) 至少等待50us。
(4) 查看震荡器失效标志位OFIFG是否清0,如果没有清0,则重复1至4步直到震荡器失效标志位OFIFG清0。
与之相关寄存器为:1.BCSCTL1和BCSCTL2(基础系统时钟控制寄存器)2.IE1中断使能寄存器的第二位OFIE,振荡器失效中断使能位。
3.IFG1中断标志寄存器的第二位OFIFG,振荡器失效标志位。
4.DCOCTL数字震荡器控制寄存器。
一. BCSCTL1设置(基础系统时钟控制寄存器1):1.XT2OFF=0,外部高速晶体开。
2.XTS=0,片外低速晶体的频率,0为低频模式。
3.DIVAx=00B,不将其进行分频,即分频比为14.XT5V不使用设为0。
5.RSELx=111,DOC的电阻选择,此时DOC震荡频率达到最大10000MHZ(理想状态)。
因此BCSCTL1=0000 0111B=0x47。
二.BCSCTL2设置(基础系统时钟控制寄存器2):1.SELMx=10B,选择片外高速晶体作为MCLK。
这两位应等到振荡器失效标志位清0后才置位2.DIVMx=00B,不将其进行分频,即分频比为13.SELS=0B,选择子系统时钟为DCO4.DIVSx=00B,不将其进行分频,即分频比为15.DCOR=0B,选择芯片内部电阻。
三.DCOCTL(数字震荡器控制寄存器)1.DCOx=111,DCO频波段选择,此时诜择最大2.MODx=000,调制选择,当DCOx=111B时MODx无效。
*//*下面将片外高速晶体设为主系统时钟。
*///(1) 起动片外高速晶体BCSCTL1&=~XT2OFF;//XT2OFF的宏为0x80。
单片机MSP430F149-DS1302读写及串口收发程序
/********************************************************* 文件名称:* IIC.c* 文件说明:* 使用口线模拟IIC* 程序使用波特率为2400,程序运行时需要在pc机上使用一个串口* 接收发送程序,任意发送字符,接收的字符为十六进制时间数据* MSP-FET430P149 Demo - Basic Clock, MCLK Sourced from HF XTAL XT2* L.TCH* Feb 2007* Built with IAR Embedded Workbench Version: 3.10A*******************************************************//*********************************************************/#include <MSP430X14X.h>/********************************************************** 定义*********************************************************/#define RST BIT7#define SDA BIT6#define SCLK BIT5char pbuf[7];char clok[7]={0x16,0x15,0x14,0x13,0x12,0x04,0x07};char cbuf;char bbuf;char *pda;char *pck;char *prg;/************************************************说明************************************************/void Port_Init(void);void Init_CLK(void);void Init_UART0(void);void RST_Enable(void);void RST_Disable(void);void SCLK_HI(void);void SCLK_LO(void);void WriteByte(char nVal);char ReadByte(void);void WriteTo1302(char nAddr, char nVal);char ReadFrom1302(char nAddr);void BurstWriteTime(char *pWClock);void BurstReadTime(char *pRClock);void BurstWriteRam(char *pWReg);void BurstReadRam(char *pRReg);void SetTime(char *pClock);void GetTime(char pTime[]);/***********************************************/void Port_Init(void){P1DIR |= RST; //设置CE为输出管脚P1DIR |= RST; //设置SCLK为输出管脚P1DIR |= SCLK;P2DIR |= 0x02; // Set P2.1 to output directionreturn;}void Init_CLK(void){unsigned int i;BCSCTL1 = 0X00; //将寄存器的内容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1do{IFG1 &= ~OFIFG; // 清除OSCFault标志for (i = 0xFF; i > 0; i--);}while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1BCSCTL1 &= ~(XT2OFF + XTS); //open XT2, LFTX2 select low frequency //BCSCTL1 |= RSEL0 + RSEL1 + RSEL2; //DCO Rsel=7(Freq=3200k/25摄氏度)//BCSCTL1 |= 0x07;BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1return;}void Init_UART0(void){U0CTL = 0X00; //将寄存器的内容清零UCTL0|=SWRST;P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXDME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD UCTL0 |= CHAR; // 8-bit characterUTCTL0 |= SSEL1; // UCLK = SMCLKUBR00 = 0xD3; // 3.58Mhz/2400 -1491UBR10 = 0x05; //UMCTL0 = 0x00; // no modulationUCTL0 &= ~SWRST; // Initialize USART state machine IE1 |= URXIE0; // Enable USART0 RX interruptIE1 &= ~UTXIE0; // Disable USART TX interrupt return;}void RST_Enable(void){P1OUT |= RST;return;}void RST_Disable(void){P1OUT &= ~(RST);return;}void SCLK_HI(void){P1OUT |= SCLK;return;}void SCLK_LO(void){P1OUT &= ~(SCLK);return;}/*-------------------------------* 功能: 写入1Byte数据* 调用:* 输入: nVal 写入的数据* 返回值: 无*------------------------------*/void WriteByte(char nVal){char i,j;char nTemp = nV al;char nSend;P1DIR |= SDA; //设置DATA为输出管脚_NOP();_NOP();_NOP();_NOP();for(i = 0; i < 8; i++) //发8位,从0位开始{nSend = (nTemp & 0x01);if(nSend == 1){P1OUT |= SDA;}else{P1OUT &= ~(SDA);}SCLK_HI();for(j = 10;j > 0;j--) ;SCLK_LO();for(j = 10;j > 0;j--) ;nTemp >>= 1; //从0位开始,发8位}return;}/*--------------------------------------* 功能: 读取1Byte数据* 调用:* 输入:* 返回值: nTemp*------------------------------------*/char ReadByte(void){char nTemp = 0;int i;int j;P1DIR &=~SDA; //设置DATA为输入管脚_NOP();_NOP();_NOP();_NOP();for(i = 0; i < 8; i++) //接受8位{SCLK_HI();for(j = 10;j > 0;j--);SCLK_LO();_NOP();_NOP();if(P1IN & SDA) //如果第i位是高电平置1{nTemp |= (0x01 << i);}for(j = 10;j > 0;j--);}return nTemp;}/*-----------------------------------------* 功能: 往DS1302写入1Byte数据* 调用:* 输入: nVal 写入的数据* 返回值: 无*------------------------------------------*/void WriteTo1302(char nAddr, char nVal){RST_Disable();SCLK_LO();RST_Enable();_NOP();_NOP();_NOP();_NOP();WriteByte(nAddr); //地址,命令WriteByte(nVal); //写1Byte数据SCLK_HI();RST_Disable();return;}/*-----------------------------------------* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: nDta*-----------------------------------------*/char ReadFrom1302(char nAddr){char nData;RST_Disable();SCLK_LO();RST_Enable();_NOP();_NOP();_NOP();_NOP();WriteByte(nAddr); //地址,命令nData = ReadByte(); //读1Byte数据SCLK_HI();RST_Disable();cbuf = nData; //return(nData);}/*-------------------------------------* 功能: 往DS1302写入时钟数据(多字节方式)* 调用:* 输入: pClock[]: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码)* 返回值: 无*----------------------------------*/void BurstWriteTime(char *pClock){char i;WriteTo1302(0x8e,0x00); //控制命令,写操作.。
msp430AD采样并串口发送
msp430AD采样并串口发送#includevoid clk_init(){P5SEL |= BIT4+BIT5; // Select XT1UCSCTL6 &= ~(XT1OFF); // XT1 OnUCSCTL6 |= XCAP_3; // Internal load capUCSCTL0 = 0x0000;UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive strengthUCSCTL3 = SELREF_0+FLLREFDIV_1; // Set DCO FLL reference = XT1__bis_SR_register(SCG0); // Disable the FLL control loopUCSCTL1 = DCORSEL_3; // Select DCO range 16MHz operation UCSCTL2 =249; // Set DCO Multiplier for 8MHz // (N + 1) * FLLRef = Fdco// (249 + 1) * 32768 = 8MHz __bic_SR_register(SCG0); // Enable the FLL control loopUCSCTL4 |= SELS_0; // ACLK = LFTX1 (by default)// __delay_cycles(250000);}void adc_init(){P6SEL |= 0x01; // Enable A/D channel A0ADC12CTL0 = ADC12ON+ADC12SHT0_12+ADC12MSC; // Turn on ADC12, set sampling time// set multiple sample conversion ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2+ADC12DIV_0+ADC12SSEL_3; // Use sampling timer, set modeADC12MCTL0 |= ADC12INCH_1;ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set modeADC12IE = 0x01; // Enable ADC12IFG.0ADC12CTL0 |= ADC12ENC; // Enable conversionsADC12CTL0 |= ADC12SC; // Start conversion}void uart1(){WDTCTL = WDTPW + WDTHOLD; // Stop WDTP3SEL |= BIT3+BIT4; // P3.3,4 = USCI_A0 TXD/RXDUCA0CTL1 |= UCSWRST; // **Put state machine in reset**UCA0CTL1 |= UCSSEL_2; // SMCLKUCA0BR0 = 9; // 1MHz 115200 (see User's Guide) UCA0BR1 = 0; // 1MHz 115200UCA0MCTL |= UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE;}int main(void){P1DIR |= 0x01;//clk_init();uart1();int he;adc_init();__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled__no_operation(); // For debugger}#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector=ADC12_VECTOR__interrupt void ADC12ISR (void)#elif defined(__GNUC__)void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)#else#error Compiler not supported!#endif{switch(__even_in_range(ADC12IV,34)){case 0: break; // Vector 0: No interruptcase 2: break; // Vector 2: ADC overflowcase 4: break; // Vector 4: ADC timing overflowcase 6: // Vector 6: ADC12IFG0 UCA0TXBUF = ADC12MEM0>>4; // Move resultsP1OUT ^= 0x01;_BIC_SR_IRQ(LPM0_bits);case 8: break; // Vector 8: ADC12IFG1case 10: break; // Vector 10: ADC12IFG2case 12: break; // Vector 12: ADC12IFG3 case 14: break; // Vector 14: ADC12IFG4 case 16: break; // Vector 16: ADC12IFG5 case 18: break; // Vector 18: ADC12IFG6 case 20: break; // Vector 20: ADC12IFG7 case 22: break; // Vector 22: ADC12IFG8 case 24: break; // Vector 24: ADC12IFG9 case 26: break; // Vector 26: ADC12IFG10 case 28: break; // Vector 28: ADC12IFG11 case 30: break; // Vector 30: ADC12IFG12 case 32: break; // Vector 32: ADC12IFG13 case 34: break; // Vector 34: ADC12IFG14 default:break;}}。
msp430串口接收函数
msp430串口接收函数篇一:基于msp430串口接收中断#includevoid main{WDTCTL = WDTPW + WDTHOLD;BCSCTL1 = CALBC1_1MHZ;DCOCTL = CALDCO_1MHZ;P1SEL |= BIT1 + BIT2;P1SEL2 |= BIT1 + BIT2;//需要对照着手册来看UCA0CTL1 |= UCSSEL_2;//选择串口的校验位 UCA0BR0 = 104;//9600 波特率的计算一般都存在误差 UCA0BR1 = 0;UCA0MCTL = UCBRS0;//校准波特率用所以要使用校准UCA0CTL1 &= ~UCSWRST;//让串口进行复位IE2 |= UCA0RXIE;//开启接收中断__bis_SR_register;}#pragma vector = USCIAB0RX_VECTOR__interrupt void USART_RECEIVE{UCA0TXBUF = UCA0RXBUF+1;while);//等待发送完毕可加可不加 }篇二:MSP430串口收发程序MSP430 标准库printf函数实现20XX-08-02 21:22关键是增加一个putchar函数。
代码如下:#include#includevoid NOP10{_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;_NOP ;}int putchar//注意不要改参数的类型和返回值的类型,否则printf调用是就有问题了。
{if{TXBUF1 = '\r';while==0);}TXBUF1 = c;while==0);return c;}void InitalUart1{P4SEL |= 0x03; // P4.0,1 = USART1 TXD/RXDME2 |= UTXE1 + URXE1;// Enable USART1 TXD/RXDUCTL1 |= CHAR; // 8-bit characterUTCTL1 |= SSEL1; // UCLK = SMCLK UBR01 = 0x36; // 1MHz 19200UBR11 = 0x00; // 1MHz 19200UMCTL1 = 0x6B; // ModulationUCTL1 &= ~SWRST; // Initalize USART state machine IE2 |= URXIE1; // Enable USART1 RX interrupt//IFG2 |= UTXIFG1;}void main{unsigned char i;i=0x10;WDTCTL = WDTPW + WDTHOLD; // Stop WDTFLL_CTL0 |= XCAP18PF;// Configure load capsInitalUart1 ;_EINT ;// LPM0;while{// while ); // USART1 TX buffer ready?// TXBUF1 = 'H';//putchar;//putchar;printf;NOP10 ;}}#pragma vector=USART1RX_VECTOR__interrupt void usart1_rx{while ); // USART1 TX buffer ready?TXBUF1 = RXBUF1; // RXBUF1 to TXBUF0//LPM0_EXIT;msp430各模块函数整合20XX-08-13 14:27/***************************************************程序功能:控制8个LED闪烁,用于测试下载功能是否正常测试说明:观察LED闪烁***************************************************/#include#include "EEPROM.c"#include "LCD1602.c"#include "DS18B20.c"void LED_delay;void KEY_delay;void EEPROM_delay;void sys_init;void LED_Init;void LED_Set;unsigned char LED_Read_Status;void LED_Test;void KEY_Init;unsigned char key;void KEY_Test;void SEG_Init;void SEG_Show;void EEPROM_Init;void Write_EEPROM;void Read_EEPROM;void LCD1602_Init;void LCD1602_Show;void DS18B20_Init;void TimerA_Delay_CFG;float get_DS18B20_temperature;unsigned char SEG_Table[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0 xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//0-f 段选信号,共阳 uchar UART_Rev_String[20]="\0";uchar rev_string_count=0;uchar rev_string_xxplete=0; //为1代表串口接收了一行字符串// =================================================== ===============// 延时函数// =================================================== ===============//************************************************* // function :LED_delay// parameter:dly// description :用于LED花样显示延时//************************************************* void LED_delay{unsigned int i;whilefor;}//************************************************* // function :KEY_delay// parameter:// description :用于消抖的延时//************************************************* void KEY_delay{uint tmp;for;}//************************************************* // function :EEPROM_delay// parameter:ts// description :用于消抖的延时//************************************************* void EEPROM_delay{while;}// =================================================== =============== // 系统函数// =================================================== ===============//************************************************* // function :sys_init// parameter:// description :延时一段时间//************************************************* void sys_init{WDTCTL = WDTPW + WDTHOLD; //关闭看门狗BCSCTL2 &=0xc0; //XT2CLK+2分频}// =================================================== =============== // LED相关函数//=================================================== ===============//************************************************* // function :LED_Init// parameter:// description :LED初始化程序// 8个LED接在P2.0~P2.7上。
430单片机双串口程序
/******************************************************程序功能:使用2串口进行串口通讯,串口1接受到01后回发给上位机01 ,否则不回。
串口2接收到02后回发给上位机02,否则不回。
为保证数据不同时占用232.在进入任何一个串口中断时,将中断使能关闭,退出中断时重新开启中断使能-------------------------------------------------------通信格式:N.8.1, 9600无校验,8个数据位,1个停止位,波特率9600------------------------------------------------------*******************************************************/#include <msp430x14x.h>/*************串口初始化函数*************************/void uart_init(void){P3SEL |= 0x30; // 选择P3.4和P3.5做UART0,P3.6.P3.7做UART1P3SEL |= 0xC0; //将P3.6,P3.7选做UART1的通信端口ME1 |= UTXE0 + URXE0; // 使能USART0的发送和接受ME2 |= UTXE1 + URXE1; //使能USART1的TXD和RXDUCTL0 |= CHAR; // 选择8位字符UCTL1 |= CHAR; //选择8-bit字符UTCTL0 |= SSEL0; // 都使用UCLK = ACLKUTCTL1 |= SSEL0; //驱动时钟选择ACLKUBR00 = 0x03; // 波特率9600UBR10 = 0x00;UMCTL0 = 0x4A; // 波特率校验,具体见430用户手册UBR01 = 0x03; //波特率2400UBR11 = 0x00;UMCTL1 = 0x4A; //调整UCTL0 &= ~SWRST; // 初始化UART0状态机UCTL1 &= ~SWRST; //初始化UART状态机IE1 |= URXIE0; // 使能USART0的接收中断IE2 |= URXIE1;}//时钟出使化函数void int_clk()unsigned char i;BCSCTL1&=~XT2OFF;BCSCTL2|=SELM1+SELS;do{IFG1&=~OFIFG;for(i=0;i<100;i++)_NOP();}while((IFG1&OFIFG));IFG1&=~OFIFG;}/********************主函数********************/void main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗int_clk();uart_init(); //串口初始化while(1){_EINT(); //打开全局中断}}/*******************************************函数名称:UART0_RXISR功能:UART0的接收中断服务函数,在这里唤醒CPU,使它退出低功耗模式参数:无返回值:无********************************************/#pragma vector = UART0RX_VECTOR__interrupt void UART0_RXISR(void){if(RXBUF0==0x01) //确定数据位01 {_DINT(); //关闭全局中断while (!(IFG1 & UTXIFG0)); //等待以前的字符发送完毕TXBUF0 = RXBUF0; //将收到的字符发送出去IFG1 &= ~UTXIFG0;}else{_DINT();}}/*******************************************函数名称:UART1_RXISR功能:UART1的接收中断服务函数,在这里唤醒CPU,使它退出低功耗模式参数:无返回值:无********************************************/#pragma vector = UART1RX_VECTOR //中断入口__interrupt void UART1_RXISR(void){if(RXBUF1==0x02) //确定数据位02{_DINT(); //关闭全局中断while(!(IFG2 & UTXIFG1)); //等待发送结束TXBUF1 = RXBUF1; //将接收到的数据发送出去IFG2 &= ~UTXIFG1;}else{_DINT();}}。
NRF24L01 MSP430发送接收程序(word文档良心出品)
NRF24L01 MSP430发送接收程序作者:codebaby 文章来源:codebaby 点击数: 1351 更新时间:2011-8-18最近弄了几天的无线模块,玩的是NRF2L01,因为这款无线模块价格便宜,网上也就卖10多块钱!刚开始用51写,“百度一下”发现网上的程序真是百篇一律,你抄我,我抄你。
对比了几个程序之后,发现他们的程序注释也是自相矛盾,看了的唯一收获就是,结合技术资料,对NRF24L01的工作模式和通信过程有了个总体的把握。
用51调了几次没成功,改而用430板子来写。
在网上查了一些相关的程序,终于成功了。
现在发现其实要写对NRF24L01的基本通信程序并不难,当然要玩转它又是另外一回事了。
我也刚刚才玩会单通道接收发送这个工作模式,其他的工作模式还没玩!还是附上相应的程序供大家学习交流,当然程序可能难免还有疏漏和错误,还望比拼指出!这是NRF24L01的头文件配置程序:#include <msp430x14x.h>//=======================NRF24L01_CE 端口========================================= #define RF24L01_CE_0 P3OUT &=~BIT1#define RF24L01_CE_1 P3OUT |= BIT1//=============================RF24L01_CSN 端口================================== #define RF24L01_CSN_0 P3OUT &=~BIT3#define RF24L01_CSN_1 P3OUT |= BIT3//=============================RF24L01_SCK 端口====================================== #define RF24L01_SCK_0 P3OUT &=~BIT2#define RF24L01_SCK_1 P3OUT |= BIT2//=============================RF24L01_MISO 端口=========================================#define RF24L01_MISO_0 P3OUT &=~BIT0#define RF24L01_MISO_1 P3OUT |= BIT0//============================= RF24L01_MOSI 端口================================ #define RF24L01_MOSI_0 P2OUT &=~BIT6#define RF24L01_MOSI_1 P2OUT |= BIT6//==========================IRQ 状态============================================ #define RF24L01_IRQ_0 P2OUT &=~BIT7#define RF24L01_IRQ_1 P2OUT |= BIT7//==========================NRF24L01地址,接收发送数据长度=============================== =============#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 32 TX payload //这里可以更改你想要发送和接收的数据长度如果是发指令我喜欢越短越好#define RX_PLOAD_WIDTH 32 // 32 uints TX payload//=========================NRF24L01寄存器指令===================================#define READ_REG 0x00 // 读寄存器指令#define WRITE_REG 0x20 // 写寄存器指令#define RD_RX_PLOAD 0x61 // 读取接收数据指令#define WR_TX_PLOAD 0xA0 // 写待发数据指令#define FLUSH_TX 0xE1 // 冲洗发送FIFO指令#define FLUSH_RX 0xE2 // 冲洗接收FIFO指令#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令#define NOP1 0xFF // 保留//========================SPI(nRF24L01)寄存器地址===============================#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式#define EN_AA 0x01 // 自动应答功能设置#define EN_RXADDR 0x02 // 可用信道设置#define SETUP_AW 0x03 // 收发地址宽度设置#define SETUP_RETR 0x04 // 自动重发功能设置#define RF_CH 0x05 // 工作频率设置#define RF_SETUP 0x06 // 发射速率、功耗功能设置#define STATUS 0x07 // 状态寄存器#define OBSERVE_TX 0x08 // 发送监测功能#define CD 0x09 // 地址检测#define RX_ADDR_P0 0x0A // 频道0接收数据地址#define RX_ADDR_P1 0x0B // 频道1接收数据地址#define RX_ADDR_P2 0x0C // 频道2接收数据地址#define RX_ADDR_P3 0x0D // 频道3接收数据地址#define RX_ADDR_P4 0x0E // 频道4接收数据地址#define RX_ADDR_P5 0x0F // 频道5接收数据地址#define TX_ADDR 0x10 // 发送地址寄存器#define RX_PW_P0 0x11 // 接收频道0接收数据长度#define RX_PW_P1 0x12 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//=============================RF24l01状态=====================================char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址//我刚开始学的时候对这个发送和接收地址不是很明白,为什么他要设置成这样,后来才知道这个地址是用户自己定的,也就是说不是每个芯片只有唯一的地址,只要发送和接收端的地址一致就行char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址char sta;char TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; //这个程序要发送的数据void RF24L01_IO_set(void);void ms_delay(void);void InitSys();void Delay(int s);char SPI_RW(char data);char SPI_Read(char reg);char SPI_RW_Reg(char reg, char value);char SPI_Read_Buf(char reg, char *pBuf, char uchars);char SPI_Write_Buf(char reg, char *pBuf, char uchars);void SetRX_Mode(void);char nRF24L01_RxPacket(char* rx_buf);void nRF24L01_TxPacket(char * tx_buf);void init_NRF24L01(void);//===========================RF24L01端口设置========================================== void RF24L01_IO_set(void){P2DIR &= 0x7f; P2DIR |= 0x40; P2SEL&=0x3F; P2IE=P2IE&0x3f;P3DIR &= 0xFE; P3DIR |= 0x0E; P3SEL&=0xF0;}//******************************************************************************//系统初始化打开430XT2晶振//******************************************************************************void InitSys(){unsigned int iq0;_DINT();BCSCTL1 &=~XT2OFF;do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM1+SELS; // MCLK,SMCLK时钟为XT2}//========================延时约5ms============================================= void ms_delay(void){unsigned int i=40000;while (i != 0){i--;}}//========================================长延时================================ void Delay(int s){unsigned int i,j;for(i=0; i<s; i++);for(j=0; j<s; j++);}//****************************************************************************************** //延时函数//****************************************************************************************** void inerDelay_us(char n){for(;n>0;n--);}//============================================================================== //函数:uint SPI_RW(uint uchar)//功能:NRF24L01的SPI写时序//******************************************************************************char SPI_RW(char data){char i,temp=0;for(i=0;i<8;i++) // output 8-bit{if((data & 0x80)==0x80){RF24L01_MOSI_1; // output 'uchar', MSB to MOSI}else{RF24L01_MOSI_0;}data = (data << 1); // shift next bit into MSB..temp<<=1;RF24L01_SCK_1; // Set SCK high..if((P3IN&0x01)==0x01)temp++; // capture current MISO bitRF24L01_SCK_0; // ..then set SCK low again}return(temp); // return read uchar}//*********************************************************************************************** *****//函数:uchar SPI_Read(uchar reg)//功能:NRF24L01的SPI时序//*********************************************************************************************** *****char SPI_Read(char reg){char reg_val;RF24L01_CSN_0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueRF24L01_CSN_1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}//*********************************************************************************************** *****///功能:NRF24L01读写寄存器函数//*********************************************************************************************** *****/char SPI_RW_Reg(char reg, char value){char status1;RF24L01_CSN_0; // CSN low, init SPI transactionstatus1 = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..RF24L01_CSN_1; // CSN high againreturn(status1); // return nRF24L01 status uchar}//*********************************************************************************************** *****///函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数//****************************************************************************************************/char SPI_Read_Buf(char reg, char *pBuf, char chars){char status2,uchar_ctr;RF24L01_CSN_0; // Set CSN low, init SPI tranactionstatus2 = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<chars;uchar_ctr++){pBuf[uchar_ctr] = SPI_RW(0);}RF24L01_CSN_1;return(status2); // return nRF24L01 status uchar}//*********************************************************************************************** **********//函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于写数据reg:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数//*********************************************************************************************** **********/char SPI_Write_Buf(char reg, char *pBuf, char chars){char status1,uchar_ctr;RF24L01_CSN_0; //SPI使能status1 = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<chars; uchar_ctr++){SPI_RW(*pBuf++);}RF24L01_CSN_1; //关闭SPIreturn(status1);}//*********************************************************************************************** *****///函数:void SetRX_Mode(void)//功能:数据接收配置//*********************************************************************************************** *****/void SetRX_Mode(void){RF24L01_CE_0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收RF24L01_CE_1;inerDelay_us(130); //注意不能太小}//*********************************************************************************************** *******///函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)//功能:数据读取后放如rx_buf接收缓冲区中//*********************************************************************************************** *******/char nRF24L01_RxPacket(char* rx_buf){char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(sta&0x40) // 判断是否接收到数据{RF24L01_CE_0 ; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer revale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}//*********************************************************************************************** ************//函数:void nRF24L01_TxPacket(char * tx_buf)//功能:发送tx_buf中数据//*********************************************************************************************** ***********/void nRF24L01_TxPacket(char * tx_buf){RF24L01_CE_0 ; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送RF24L01_CE_1; //置高CE,激发数据发送inerDelay_us(10);}//****************************************************************************************//NRF24L01初始化//***************************************************************************************/void init_NRF24L01(void){inerDelay_us(100);RF24L01_CE_0 ; // chip enableRF24L01_CSN_1; // Spi disableRF24L01_SCK_0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Pa ge21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0E); // IRQ收发完成中断响应,16位CRC ,主接收}}//=============================================================================下面是发送主程序:#include <msp430x14x.h>#include "NRF24L01.h"void main(){WDTCTL = WDTPW + WDTHOLD; //禁止看门狗RF24L01_IO_set();InitSys();init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // 将要发送的数据转移到发送缓冲区while(1){nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器ms_delay();ms_delay();LED1_1;ms_delay();ms_delay();LED1_0;}}下面是接收主程序:将接收到的数据发送到PC 可以通过串口助手来查看接收到数据是否正确#include <msp430x14x.h>#include "NRF24L01.h"char RxBuf[32]={0};//===============================串口初始化=====================================void init_uart0(void){//====================串口工作模式设置========================================U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当CHAR=1时为8位数据//不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置========================================U0TCTL=0x00; //U0TCTL包含串口0发送功能操作U0TCTL +=SSEL0; //波特率发生器选择ACLK//#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。
msp430无线收发实验
实验十七无线收发实验一.实验目的1.熟悉并学习使用开发板上的无线通信模块(NRF24L01)2.复习串口以及GPIO的应用3.掌握SPI的基本知识4.理解NRF24L01无线模块的基本工作原理二.实验原理24LnRF24L01是一款工作在~世界通用ISM频段的单片无线收发器芯片无线收发器包括:频率发生器增强型SchockBurstTM模式控制器、功率放大器、晶体振荡器、调制器解调器输、出功率频道选择和协议的设置可以通过SPI接口进行设置。
极低的电流消耗当工作在发射模式下发射功率为-6dBm时电流消耗为接收模式时为掉电模式和待机模式下电流消耗更低。
我们需要格外注意一下几个参数:(1)供电电压~(2)数据传输率1或2Mbps(3)SPI接口数据速率0~8Mbps(4)可接受5V电平的输入(5)125个可选工作频道(信道)表1 NRF24L01管脚定义SPI(Serial Peripheral Interface)串行外围模块接口是Motorola首先在其MC68HCXX系列处理器上定义的,它是一种同步的高速串行通信协议。
这里我们需要注意的一点是串行异步通信,也就是我们平常所说的串口,是不需要时钟同步,所以叫做串行异步通信,而SPI需要时钟进行同步,这就是两者的区别所在。
SPI总线系统是一种同步串行外设接口;是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。
SPI有主从两种工作方式,可以工作在3线或者4线模式下。
先简单介绍一下3线模式,3线模式的管脚定义如表2所示SIMO 从进主出数据输出引脚数据输入引脚SOMI 从出主入数据输入引脚数据输出引脚UCLK USART时钟输出时钟输入时钟表2线模式管脚定义写到这里大家可以有些疑问为什么在我们介绍NRF24L01的过程中,我们认为MOSI管脚是输入管脚,而SPI介绍中SIMO既可以输入也可以是输出,在NRF24L01过程中,我们认为MISO是输出管脚,而SPI介绍中SOMI既可以输入也可以是输出,其实这个问题的答案很简单,就是无论是接收还是发送NRF24L01一直处于从机模式,那么就和上表中的定义是完全符合的,由此我们也可以知道,单片机中无论是收还是发都是处于主机模式。
MSP430单片机串口通信实例(已验证)
/*main.c******************************************************************************* 功能:串口通信日期:2013.9.11姓名:MRTnotice:无论接收发送只要标志位(TI RI)置位立马进入中断一般情况即使中断不允许的情况下buffer中任然接收到数据并存储******************************************************************************* ***/#include"msp430x14x.h"#include"whole.h"#include"main.h"struct power guss;unsigned char buffer_value;void main(){WDTCTL = WDTPW + WDTHOLD;init_usart();init_clk();_EINT();while(1){}}#pragma vector = USART0RX_VECTOR__interrupt void usart0_rx(void){buffer_value++;guss.buffer[0] = RXBUF0;if(buffer_value==1){guss.buffer[1] = RXBUF0;guss.value = guss.buffer[1];guss.value<<=4;}if(buffer_value==2){guss.buffer[2] = RXBUF0;buffer_value = 0;}}/*******************************end*****************************************/ /**basic.c*************************************************************************功能:串口通信基础函数配置日期:2013.9.11姓名:MRTnotice:无论接收发送只要标志位(TI RI)置位立马进入中断一般情况即使中断不允许的情况下buffer中任然接收到数据并存储****/#include"msp430x14x.h"#include"whole.h"#include"main.h"void init_usart(){UTCTL0 |= SSEL1;//串口时钟源选择的是SMCLKUBR00 = 0Xa0;UBR10 = 0X01;UMCTL0 = 0Xc0;//波特率19200UCTL0 &= ~SWRST;UCTL0 = CHAR;ME1 |=UTXE0 + URXE0;//串口接收中断打开IE1 |=URXIE0; //使能接收中断}void init_clk(){unsigned int iq0;BCSCTL1&=~XT2OFF; //打开XT2振荡器do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2/}void init_io(){P4SEL |= BIT1;// P4.1接内部模块}void init_pwm(){TBCCR0 = 400;TBCCTL1 = OUTMOD_7; // CCR1 reset/setTBCCR1 = 50; // CCR1 PWM duty cycleTBCTL = TBSSEL_2 + MC_1; //}/*******************************end*****************************************/。
MSP430和TC35程序
MSP430和TC35程序#include <MSP430X14X.h>#include "uart.h"#include "TC35.h"//定义全局变量static char nComm;//定义串口操作变量char nRev_UART0; // 串口 0 的接收标志char nRev_UART1; // 串口 1 的接收标志char UART0_TX_BUF[200]; // 串口 0 的发送缓冲区char UART0_RX_BUF[200]; // 串口 0 的接收缓冲区char UART1_TX_BUF[50]; // 串口 1 的发送缓冲区char UART1_RX_BUF[50]; // 串口 1 的接收缓冲区char pBuf0[100];static int nTX1_Len;static char nRX1_Len;char nRX1_Len_temp;static int nTX0_Len;static int nRX0_Len;int nRX0_Len_temp;static char nTX0_Flag;static char nTX1_Flag;int nSend_TX0;int nSend_TX1;void main(void){int j;int n;int nTemp;int nLen1;int nLen2;char nRes_UART1;char nRes_UART0;char PhoneNumber[18];char UART1_RX_Temp[50];char UART0_RX_Temp[20];char pOut1[40];char pOut2[200];char nSend;int nPhone;WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗 _DINT(); // 关闭中断nSend_TX1 = 0;nSend_TX0 = 0;nTX1_Flag = 0;nTX0_Flag = 0;nTX0_Len = 0;nTX1_Len = 0;nRX1_Len = 0;nRX0_Len = 0;nRev_UART1 = 0;nRev_UART0 = 0;nPhone = 0;nLen1 = 0;nLen2 = 0;nComm = 0;nSend = 0;/////////////////////////////////// 初始化Init_CLK();Init_UART0();Init_UART1();_EINT();//打开中断// TC35初始化tc35_init();Delay_ms(100);nTX0_Len = setCsca(UART0_TX_BUF);IFG1 |= UTXIFG0;// 设置中断标志,进入发送中断程序 Delay_ms(500);nTX0_Len = setCmgf(UART0_TX_BUF);IFG1 |= UTXIFG0;// 设置中断标志,进入发送中断程序 Delay_ms(500);//等待配置for(;;){if(nRev_UART1 == 1){nRev_UART1 = 0;for(i = 0;i < nRX1_Len;i++){UART1_RX_Temp[i] = UART1_RX_BUF[i];}//获得电话号码nPhone =SetPhone(UART1_RX_Temp,PhoneNumber,nRX1_Len);if(nPhone != 0){nTX1_Len = SetOK(UART1_TX_BUF);IFG2 |= UTXIFG1;// 设置中断标志,进入发送中断程序break;}else{nTX1_Len = SetError(UART1_TX_BUF);IFG2 |= UTXIFG1;// 设置中断标志,进入发送中断程序 }}}//循环处理for(;;){if(nComm == 1){nComm = 0;for(i = 0;i < 50;i++){pBuf[i] = i;}sendSms(PhoneNumber,nPhone,pBuf,50,&nLen1,&nLen2,pOut1,pOut 2);for(i = 0;i < nLen1;i++){UART0_TX_BUF[i] = pOut1[i];}nTX0_Len = nLen1;IFG1 |= UTXIFG0;// 设置中断标志,进入发送中断程序 //等待"> "for(;;){if(nRev_UART0 == 1){nRev_UART0 = 0;for(i = 0;i < nRX0_Len;i++){UART0_RX_Temp[i] = UART0_RX_BUF[i];}if(nRX0_Len >= 2){if((UART0_RX_Temp[0] == 62)&& (UART0_RX_Temp[1] == 32)){nSend = 1;break;}}else{nSend = 0;break;}}}for(i = 0;i < nLen2;i++){UART0_TX_BUF[i] = pOut2[i];}nTX0_Len = nLen2;IFG1 |= UTXIFG0;// 设置中断标志,进入发送中断程序Delay_ms(10000);}}}////////////////////////////////////////// 处理来自串口 0 的接收中断interrupt [UART0RX_VECTOR] void UART0_RX_ISR(void){UART0_RX_BUF[nRX0_Len_temp] = RXBUF0; //接收来自的数据nRX0_Len_temp += 1;if(UART0_RX_BUF[nRX0_Len_temp - 1] == 13){nRX0_Len = nRX0_Len_temp;nRev_UART0 = 1;nRX0_Len_temp = 0;}}////////////////////////////////////////// 处理来自串口 0 的发送中断interrupt [UART0TX_VECTOR] void UART0_TX_ISR(void){if(nTX0_Len != 0){nTX0_Flag = 0; // 表示缓冲区里的数据没有发送完TXBUF0 = UART0_TX_BUF[nSend_TX0];nSend_TX0 += 1;Delay_us(5);if(nSend_TX0 >= nTX0_Len){nSend_TX0 = 0;nTX0_Len = 0;nTX0_Flag = 1;}}}///////////////////////////////////////// 处理来自串口 1 的接收中断interrupt [UART1RX_VECTOR] void UART1_RX_ISR(void){UART1_RX_BUF[nRX1_Len_temp] = RXBUF1; //接收来自的数据nRX1_Len_temp += 1;if(UART1_RX_BUF[nRX1_Len_temp - 1] == 13){nRX1_Len = nRX1_Len_temp;nRev_UART1 = 1;nRX1_Len_temp = 0;}}///////////////////////////////////////// 处理来自串口 1 的发送中断interrupt [UART1TX_VECTOR] void UART1_TX_ISR(void){if(nTX1_Len != 0){nTX1_Flag = 0; // 表示缓冲区里的数据没有发送完TXBUF1 = UART1_TX_BUF[nSend_TX1];nSend_TX1 += 1;if(nSend_TX1 >= nTX1_Len){nSend_TX1 = 0;nTX1_Len = 0;nTX1_Flag = 1;}}}///////////////////////////////////////// 处理来自端口 1 的中断interrupt [PORT1_VECTOR] void COMM_ISR(void){if(P1IFG & BIT5){nComm = 1;P1IFG &= ~(BIT5); // 清除中断标志位Delay_us(100);}}#include "tc35.h"// 初始化int tc35_init(char pBuf[]) {pBuf[0] = 'A';pBuf[1] = 'T';pBuf[2] = 'E';pBuf[3] = '0';pBuf[4] = 13;return 5;}// 设置短信中心地址int setCsca(char pBuf[]) {pBuf[0] = 'A';pBuf[1] = 'T';pBuf[2] = '+';pBuf[3] = 'C';pBuf[4] = 'S';pBuf[5] = 'C';pBuf[6] = 'A';pBuf[7] = '=';pBuf[8] = '+';pBuf[9] = '8';pBuf[10] = '6';pBuf[11] = '1';pBuf[12] = '3';pBuf[13] = '8';pBuf[14] = '0';pBuf[15] = '0';pBuf[16] = '2';pBuf[17] = '3';pBuf[18] = '0';pBuf[19] = '5';pBuf[20] = '0';pBuf[21] = '0';pBuf[22] = ',';pBuf[23] = '1';pBuf[24] = '4';pBuf[25] = '9'; pBuf[26] = 13;return 27;}//设置短消息格式int setCmgf(char pBuf[]) {pBuf[0] = 'A';pBuf[1] = 'T';pBuf[2] = '+';pBuf[3] = 'C';pBuf[4] = 'M';pBuf[5] = 'G';pBuf[6] = 'F';pBuf[7] = '=';pBuf[8] = '0';pBuf[9] = 13;return 10;}//删除短消息int deleteSms(char pBuf[],short int index){pBuf[0] = 'A';pBuf[1] = 'T';pBuf[2] = '+';pBuf[3] = 'C';pBuf[4] = 'M';pBuf[5] = 'G';pBuf[6] = 'D';pBuf[7] = '=';pBuf[8] = (char)((index >> 8) & 0xff + 0x30); pBuf[9] = (char)(index & 0xff + 0x30);pBuf[10] = 13;return 11;}//接收短消息void revSms(char pBuf[],char pOut[]){pBuf[0] = 'A';pBuf[1] = 'T';pBuf[2] = '+';pBuf[3] = 'C';pBuf[4] = 'M';pBuf[5] = 'G';pBuf[6] = 'R';pBuf[7] = '=';pBuf[8] = (char)((index >> 8) & 0xff + 0x30);pBuf[9] = (char)(index & 0xff + 0x30);pBuf[10] = 13;return 11;}//发送短消息void sendSms(char pPhone[],int phonelen,char pData[],int nLen,int *nTXLen1,int *nTXLen2,char pOut1[],char pOut2){char strHead[18] = {'0','8','9','1','6','8','3','1','0','8','2','0','0','3','0','5','F','0'};char chrInfo[6] = {'1','1','0','0','0','B'};int nLen_temp;int nContent_Len;int nTempLen;int nOff;int nOffset;char chrTemp[100];char chrTmp[100];char pBuf[200];char phoneTemp[20];char nTemp[100];char Len[1];int i;int n;nOff = 0;nOffset = 0;for(i = 0;i < phonelen;i++){chrTmp[i] = pPhone[i];}chrTmp[phonelen] = 'F';phonelen += 1;// 将电话号码按照规范的顺序作成n = 0;for(i = 0;i < phonelen / 2;i++){phoneTemp[n++] = chrTmp[2 * i + 1];phoneTemp[n++] = chrTmp[2 * i];}copy(chrTemp,0,chrInfo,0,6);nOff = 6;chrTemp[nOff] = '8';nOff += 1;chrTemp[nOff] = '1';nOff += 1;//设置电话号码copy(chrTemp,nOff,phoneTemp,0,phonelen);nOff += phonelen;chrTemp[nOff] = '0';nOff += 1;chrTemp[nOff] = '0';nOff += 1;nContent_Len = nLen;// 设置编码类型chrTemp[nOff] = '0';nOff += 1;chrTemp[nOff] = '0';nOff += 1;Len[0] = nLen;for(i = 0;i < 10;i++){chrTmp[i] = 0;}ByteToChar(Len,chrTmp,1);chrTemp[nOff] = 'A';nOff += 1;chrTemp[nOff] = 'A';nOff += 1;copy(chrTemp,nOff,chrTmp,0,2);nOff += 2;nLen_temp = nOff;nLen_temp += nContent_Len;//获得长度的字符数组nTempLen = IntToChar(nLen_temp,chrTmp); //封装长度信息nTemp[0] = 'A';nTemp[1] = 'T';nTemp[2] = '+';nTemp[3] = 'C';nTemp[4] = 'M';nTemp[5] = 'G';nTemp[6] = 'S';nTemp[7] = '=';nOffset = 8;//长度for(i = 0;i < nTempLen;i++){nTemp[nOffset] = chrTmp[i];nOffset += 1;}nTemp[nOffset] = 13;for(i = 0; i < nOffset;i++){pOut1[i] = nTemp[i];}*nTXLen1 = nOffset;//封装内容数据copy(pOut2,0,strHead,0,18);nOffset = 18;copy(pOut2,nOffset,0,chrTemp,nOff);nOffset += nOff;Encode(pData,pBuf,nLen);ByteToChar(pBuf,chrTmp,nLen);copy(pOut2,nOffset,chrTmp,0,(2 * nLen)); nOffset += (2 * nLen);pOut2[nOffset] = 26;*nTXLen2 = nOffset;}//将源数组的内容拷贝到目的数组void copy(char pDest[],int nOrg,char pOrg[],int nStart,int nLen){int i;for(i = 0;i < nLen;i++){pDest[nOrg + i] = pOrg[i + nStart];}}// 将字节处理成字符串void ByteToChar(char nInPut[],char Out[],int nLen){int i;char chrTemp;for(i = 0;i < nLen;i++){// 高字节chrTemp = (char)((nInPut[i] >> 4) & 0x0f);if(chrTemp >= 0 && chrTemp <= 9) chrTemp += 48;else chrTemp += 55;Out[i] = chrTemp;// 低字节chrTemp = (char)(nInPut[i] & 0x0f);if(chrTemp >= 0 && chrTemp <= 9) chrTemp += 48;else chrTemp += 55;Out[i] = chrTemp;}return;}// 数的范围为250以内int IntToChar(int n,char Out[]){int i;char chrTemp1;char chrTemp2;char chrTemp3;int nLen;chrTemp1 = n / 100;chrTemp2 = (n - chrTemp1 * 100) / 10;chrTemp3 = n - chrTemp1 * 100 - chrTemp2 * 10; if(chrTemp1 != 0){nLen = 3;Out[0] = chrTemp1 + 0x30;Out[1] = chrTemp2 + 0x30;Out[2] = chrTemp3 + 0x30;}else{if(chrTemp2 != 0){nLen = 2;Out[0] = chrTemp2 + 0x30;Out[1] = chrTemp3 + 0x30;}else{nLen = 1;Out[0] = chrTemp3 + 0x30;}}return nLen;}// 编码函数void Encode(char in[],char out[],int nLen){int nOrigin = 0;int nCode = 0;while(true){if(nOrigin >= nLen) break;out[nCode] = in[nOrigin];if((nOrigin + 1) >= nLen) break;out[nCode] |= (byte)((in[nOrigin + 1] & 0x01) << 7); out[nCode + 1] = (byte)((in[nOrigin + 1] >> 1) & 0xff);if((nOrigin + 2) >= nLen) break;out[nCode + 1] |= (byte)((in[nOrigin + 2] & 0x03) << 6);out[nCode + 2] = (byte)((in[nOrigin + 2] >> 2) & 0xff);if((nOrigin + 3) >= nLen) break;out[nCode + 2] |= (byte)((in[nOrigin + 3] & 0x07) << 5);out[nCode + 3] = (byte)((in[nOrigin + 3] >> 3) & 0xff);if((nOrigin + 4) >= nLen) break;out[nCode + 3] |= (byte)((in[nOrigin + 4] & 0x0f) << 4);out[nCode + 4] = (byte)((in[nOrigin + 4] >> 4) & 0xff);if((nOrigin + 5) >= nLen) break;out[nCode + 4] |= (byte)((in[nOrigin + 5] & 0x1f) << 3);out[nCode + 5] = (byte)((in[nOrigin + 5] >> 5) & 0xff);if((nOrigin + 6) >= nLen) break;out[nCode + 5] |= (byte)((in[nOrigin + 6] & 0x3f) << 2);out[nCode + 6] = (byte)((in[nOrigin + 6] >> 6) & 0xff);if((nOrigin + 7) >= nLen) break;out[nCode + 6] |= (byte)((in[nOrigin + 7] & 0x7f) << 1);nCode += 7;nOrigin += 8;}}int AnalyseSms(char in[],int nLen,char chrPhone[],char chrMessage[]){char Phone[20];int phone_len;char chrTemp[200];char chrMessage[140];int nLen_temp;int nTempLen;int nOffset;int nOff;char chrTmp;int n;int nContent_Len;byte content[140];//去掉+CMGR:信息nLen_temp = nLen - 6;nOffset = 6;copy(chrTemp,0,in,nOffset,nLen_temp);if(nLen_temp < 20) return -1;chrTmp = chrTemp[0];if(chrTmp == '1')//新消息{chrTmp = strTemp[3];if(chrTemp == '1')// 长度为三个字符{nTempLen = (strTemp[3] - 48) * 100 + (strTemp[4] - 48) * 10+ (strTemp[4] - 48);if(nLen_temp >= 26){nLen_temp -= 26;nOffset += 26;copy(chrTemp,0,in,nOffset,nLen_temp);}else return -1;}// 长度为两个字符else{nTempLen = (strTemp[3] - 48) * 10 + (strTemp[4] - 48);if(nLen_temp >= 25){nLen_temp -= 25;nOffset += 25;copy(chrTemp,0,in,nOffset,nLen_temp);}else return -1;}//取得电话号码int nPhone_Len = 0;if(nLen_temp >= 18){copy(Phone,0,chrTemp,0,18);phone_len = (int)(Phone[1] - 48);copy(chrPhone,0,Phone,4,14);}else return -1;//获得电话号码的正确顺序copy(Phone,0,chrPhone,0,14);n = 0;for(i = 0;i < 7;i++){chrPhone[n++] = Phone[2 * i + 1];chrPhone[n++] = Phone[2 * i];}if(nLen_temp >= 20){nLen_temp -= 20;nOffset += 20;copy(chrTemp,0,in,nOffset,nLen_temp);}else return -1;if(nLen_temp >= 16){nLen_temp -= 16;nOffset += 16;copy(chrTemp,0,in,nOffset,nLen_temp);}else return -1;// 取出内容的长度nContent_Len = 0;if(nLen_temp >= 2){if((strTemp[1] >= 48) && (strTemp[1] <= 57)) nContent_Len = (strTemp[0] - 48) * 16 + (strTemp[1] - 48);else if(strTemp[1] >= 65 && strTemp[1] <= 70)nContent_Len = (strTemp[0] - 48) * 16 + (strTemp[1] - 55);else if(strTemp[1] >= 97 && strTemp[1] <= 102) nContent_Len = (strTemp[0] - 48) * 16 +(strTemp[1] - 87);}else return -1;if(strTemp.length() >= 2){nLen_temp -= 2;nOffset += 2;copy(chrTemp,0,in,nOffset,nLen_temp);}else return -1;CharToByte(strTemp,content,nLen_temp);nLen_temp /= 2;n = Decode(content,chrMessage,nLen_temp);}return n;}int FindERROR(char in[],int nLen){int nOffset,i;nOffset = -1;if(nLen < 5) return nOffset;for(i = 0;i < nLen;i++){if((in[i] == 'R') && (in[i - 1] == 'O') && (in[i - 2] == 'R')&& (in[i - 3] == 'R') && (in[i - 4] == 'E')){nOffset = i - 4;break;}}return nOffset;}int FindCMGR(char in[],int nLen){int nOffset,i;nOffset = -1;if(nLen < 5) return nOffset;for(i = 0;i < nLen;i++){if((in[i] == 'R') && (in[i - 1] == 'G') && (in[i - 2] == 'M')&& (in[i - 3] == 'C') && (in[i - 4] == '+')){nOffset = i - 4;break;}}return nOffset;}int FindOK(char in[],int nLen){int nOffset,i;nOffset = -1;if(nLen < 2) return nOffset;for(i = 0;i < nLen;i++){if((in[i] == 'K') && (in[i - 1] == 'K')){nOffset = i - 1;break;}}return nOffset;}void CharToByte(char in[],char out[],int nLen) {char chrHi,chrLow;for(int i = 0;i < nLen / 2;i++){chrHi = in[2 * i];if(chrHi >= 48 && chrHi <= 57)chrHi = (char)(chrHi - 48);else if(chrHi >= 65 && chrHi <= 70)chrHi = (char)(chrHi - 55);else if(chrHi >= 97 && chrHi <= 102) chrHi = (char)(chrHi - 87);chrLow = in[2 * i + 1];if(chrLow >= 48 && chrLow <= 57)chrLow = (char)(chrLow - 48);else if(chrLow >= 65 && chrLow <= 70) chrLow = (char)(chrLow - 55);else if(chrLow >= 97 && chrLow <= 102) chrLow = (char)(chrLow - 87);out[i] = (byte)(chrHi * 16 + chrLow); }return;}int Decode(char in[],char out[],int nLen){int nLenTemp = byteStream.length;int nOrigin = 0;int nCode = 0;nLenTemp = nLen * 8 / 7;while(true){if(nOrigin >= nLen) break;out[nCode] = (char)(in[nOrigin] & 0x7f);if((nOrigin + 1) >= nLen) break;out[nCode + 1] = (char)((in[nOrigin + 1] & 0x3f) << 1);out[nCode + 1] += (char)((in[nOrigin] & 0x80) >> 7);if((nOrigin + 2) >= nLen) break;out[nCode + 2] = (char)((in[nOrigin + 2] & 0x1f) << 2);out[nCode + 2] += (char)((in[nOrigin + 1] & 0xc0) >> 6);if((nOrigin + 3) >= nLen) break;out[nCode + 3] = (char)((in[nOrigin + 3] & 0x0f) << 3);out[nCode + 3] += (char)((in[nOrigin + 2] & 0xe0) >> 5);if((nOrigin + 4) >= nLen) break;out[nCode + 4] = (char)((in[nOrigin + 4] & 0x07) << 4);out[nCode + 4] += (char)((in[nOrigin + 3] & 0xf0) >> 4);if((nOrigin + 5) >= nLen) break;out[nCode + 5] = (char)((in[nOrigin + 5] & 0x03) << 5);out[nCode + 5] += (char)((in[nOrigin + 4] & 0xf8) >> 3);if((nOrigin + 6) >= nLen) break;out[nCode + 6] = (char)((in[nOrigin + 6] & 0x01) << 6);out[nCode + 6] += (char)((in[nOrigin + 5] & 0xfc) >> 2);out[nCode + 7] = (char)((in[nOrigin + 6] & 0xfe) >> 1);nCode += 8;nOrigin += 7;}return nLenTemp;}int tc35_init(char pBuf[]);int setCsca(char pBuf[]);int setCmgf(char pBuf[]);int deleteSms(char pBuf[]);void revSms(char pBuf[],char pOut[]);void sendSms(char pPhone[],int phonelen,char pData[],int nLen,int *nTXLen1,int *nTXLen2,char pOut1[],char pOut2);int IntToChar(int n,char Out[]);void ByteToChar(char nInPut[],char Out[],int nLen);void copy(char pDest[],int nOrg,char pOrg[],int nStart,int nLen);void Encode(char in[],char out[],int nLen);int AnalyseSms(char in[],int nLen,char chrPhone[],char chrMessage[]);int FindERROR(char in[],int nLen);int FindCMGR(char in[],int nLen);int FindOK(char in[],int nLen);void CharToByte(char in[],char out[],int nLen);int Decode(char in[],char out[],int nLen);#include <MSP430X14X.h>#include "UART.h"void Init_CLK(void){unsigned int i;BCSCTL1 = 0X00; //将寄存器的内容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1do{IFG1 &= ~OFIFG; // 清除OSCFault标志for (i = 0x20; i > 0; i--);}while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1BCSCTL1 &= ~(XT2OFF + XTS);//open XT2, LFTX2 select low frequencyBCSCTL1 |= RSEL0 + RSEL1 + RSEL2; //DCORsel=7(Freq=3200k/25摄氏度)BCSCTL1 |= 0x07;BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1}void Init_UART0(void){U0CTL = 0X00; //将寄存器的内容清零U0CTL += CHAR; //数据位为8bitU0TCTL = 0X00; //将寄存器的内容清零U0TCTL += SSEL1; //波特率发生器选择SMCLKUBR0_0 = 0Xa1; //波特率为19200UBR1_0 = 0X01;UMCTL_0 = 0X49; //调整寄存器ME1 |= UTXE0 + URXE0; //使能UART0的TXD和RXDIE1 |= URXIE0; //使能UART0的RX中断IE1 |= UTXIE0; //使能UART0的TX中断P3SEL |= BIT4; //设置P3.4为UART0的TXDP3SEL |= BIT5; //设置P3.5为UART0的RXDP3DIR |= BIT4; //P3.4为输出管脚return;}void Init_UART1(void){U1CTL = 0X00; //将寄存器的内容清零U1CTL += CHAR; //数据位为8bitU1TCTL = 0X00; //将寄存器的内容清零U1TCTL += SSEL1; //波特率发生器选择SMCLKUBR0_1 = 0X45; //波特率为115200UBR1_1 = 0X00;UMCTL_1 = 0X00;ME2 |= UTXE1 + URXE1; //使能UART1的TXD和RXD IE2 |= URXIE1; //使能UART1的RX中断IE2 |= UTXIE1; //使能UART1的TX中断P3SEL |= BIT6; //设置P3.6为UART1的TXDP3SEL |= BIT7; //设置P3.7为UART1的RXDP3DIR |= BIT6; //P3.6为输出管脚return;}void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟{unsigned long nCount;int i;unsigned long j;nCount = 2667;for(i = nValue;i > 0;i--){for(j = nCount;j > 0;j--);}return;}void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟{int nCount;int i;int j;nCount = 3;for(i = nValue;i > 0;i--){for(j = nCount;j > 0;j--);}return;}int SetOK(char UART1_TX_BUF[]){UART1_TX_BUF[0] = 'O';UART1_TX_BUF[1] = 'K';UART1_TX_BUF[2] = 13;return 3;}int SetError(char UART1_TX_BUF[]){UART1_TX_BUF[0] = 'E';UART1_TX_BUF[1] = 'R';UART1_TX_BUF[2] = 'O';UART1_TX_BUF[3] = 'R';UART1_TX_BUF[4] = 'R';UART1_TX_BUF[5] = 13;return 6;}int SetPhone(char recv[],char phone[],int nLen) {int i;char chrHi,chrLo;chrHi = recv[0];//长度chrLo = recv[1];if(recv[1] == ','){for(i = 0;i < chrHi;i++){phone[i] = recv[i + 2];}}else return 0;return chrHi;}void Init_CLK(void);void Init_UART0(void)void Init_UART1(void);int SetOK(char UART1_TX_BUF[]);int SetError(char UART1_TX_BUF[]);int SetPhone(char recv[],char phone[],int nLen);。
MSP430串口使用总结
CHAR:UxCTL Bit 4 Character length,7-bit or 8-bit character length 0:7-bit data 1:8-bit data SWRST:UxCTL Bit 0 Software reset enable 0:Disabled,USART reset released for operation 1:Eable,USART logic held in reset state } 4、3 UxTCTL(UTCTLx),USART Transmit Control Register { SSELx:Bits 5-4 Source select,These bits select the BRCLK source clock 00:UCLKI 01:ACLK 10:SMCLK 11:SMCLK } UxBR0,USART Baud Rate Control Register 0,低 8 位 UxBR1,USART Baud Rate Control Register 1,高 8 位 UxMCTL,USART Modulation Control Register UxMCTL Bits 7-0:Modulation bits, these bits select the modulation for BRCLK IFG1,Interrupt Flag Register 1 UTXIFG0: IFG1 Bit 7,USART0 transmit interrupt flag, UTXIFGO is set when UOTXBUF is 0:No interrupt pending//不挂起中断 1:Interrupt pending//等待中断处理 URXIFG0:IFG1 Bit 6 ,USART0 receive interrupt flag,URXIFG0 is set when U0RXBUF has received. 0:No interrupt pending 1:Interrupt pending 4、7 IE1,Interrupt Enable Register 1 UTXIE0 Bit 7,USART0 transmit interrupt enable.This bit enables the UTXIFG0 interrupt 0:Interrupt not enable 1:Interrupt enable URXIE0 Bit 6 USART0 receive interrupt enable.This bit enables the URXIFG0 interrupt 0:Interrupt not enable 1:Interrupt enable
msp430 ADC多通道采集以及12864液晶显示以及串口发送
//ADC.H#ifndef __ADC_H#define __ADC_H#include <msp430x14x.h>#define uchar unsigned char#define uint unsigned intextern void Trans_val(uchar x,uchar y,uint Hex_Val);extern void ADC_Init();#endif//ADC.C#include <msp430x14x.h>#include "USART0.h"#include"ADC.h"#include "lcd12864.h"#define Num_of_Results 128static uint results0[Num_of_Results]; //保存ADC转换结果的数组static uint results1[Num_of_Results]; //保存ADC转换结果的数组static uint results2[Num_of_Results]; //保存ADC转换结果的数组static uint results3[Num_of_Results]; //保存ADC转换结果的数组//ADC初始化void ADC_Init(){P6SEL = 0x0F; // Enable A/D channel inputsADC12CTL0 = ADC12ON+MSC+SHT0_2; // Turn on ADC12, set sampling time ADC12CTL1 = SHP+CONSEQ_1; // Use sampling timer, single sequence ADC12MCTL0 = INCH_0; // ref+=A Vcc, channel = A0ADC12MCTL1 = INCH_1; // ref+=A Vcc, channel = A1ADC12MCTL2 = INCH_2; // ref+=A Vcc, channel = A2ADC12MCTL3 = INCH_3+EOS; // ref+=A Vcc, channel = A3, end seq. ADC12IE = 0x08; // Enable ADC12IFG.3ADC12CTL0 |= ENC; // Enable conversions}/*******************************************函数名称:Trans_val功能:将16进制ADC转换数据变换成三位10进制真实的模拟电压数据,并在液晶上显示参数:Hex_V al--16进制数据n--变换时的分母等于2的n次方返回值:无********************************************/void Trans_val(uchar x,uchar y,uint Hex_Val){unsigned long caltmp;uint Curr_Volt;caltmp = Hex_Val;caltmp = (caltmp << 5) + Hex_Val; //caltmp = Hex_V al * 33 caltmp = (caltmp << 3) + (caltmp << 1); //caltmp = caltmp * 10Curr_Volt = caltmp >> 12; //Curr_V olt = caltmp / 2^n Display_Value(x,y,Curr_V olt);}/*******************************************函数名称:ADC12ISR功能:ADC中断服务函数,在这里用多次平均的计算P6.0口的模拟电压数值参数:无返回值:无********************************************/#pragma vector=ADC_VECTOR__interrupt void ADC12ISR (void){static uint index = 0;results0[index++] = ADC12MEM0; // Move resultsresults1[index++] = ADC12MEM1; // Move resultsresults2[index++] = ADC12MEM2; // Move resultsresults3[index++] = ADC12MEM3; // Move resultsif(index == Num_of_Results){uchar i;unsigned long sum0=0,sum1=0,sum2=0,sum3=0;index = 0;for(i = 0; i < Num_of_Results; i++){sum0 += results0[i];sum1 += results1[i];sum2 += results2[i];sum3 += results3[i];}sum0 >>= 5; //除以32sum1 >>= 5; //除以32sum2 >>= 5; //除以32sum3 >>= 5; //除以32Display_Num(3,1,sum0);Display_Num(3,2,sum1);Display_Num(3,3,sum2);Display_Num(3,4,sum3);Trans_val(5,1,sum0);Trans_val(5,2,sum1);Trans_val(5,3,sum2);Trans_val(5,4,sum3);}_BIC_SR_IRQ(LPM0_bits); // Clear LPM0, SET BREAKPOINT HERE}//USART.C#include "USART0.h"//以下是串口0的初始化设置void Usart0_Init(){P3SEL |= 0x30; // P3.4,5选择为UART收发端口ME1 |= UTXE0 + URXE0; // 使能USART0收发UCTL0 |= CHAR; // 8-bit characterUTCTL0 |= SSEL0; // UCLK = ACLKUBR00 = 0x0D; // 32k/2400 - 13.65UBR10 = 0x00; //UMCTL0 = 0x6B; // ModulationUCTL0 &= ~SWRST; // 初始化UART0状态机IE1 |= URXIE0; // 使能接收中断}//此函数用来发送一个char型void SentData(uchar num){while (!(IFG1 & UTXIFG0));TXBUF0 = num;}//此函数用来把1~4位十进制数据转化为ASCII编码的形式发送给上位机void Sent_Num(uint num){uchar ge,shi,bai,qian;qian = num/1000;bai = num/100 %10;shi = num/10%10;ge = num%10;SentData(qian+0x30);SentData(bai+0x30);SentData(shi+0x30);SentData(ge+0x30);// SentData('\n');}/*******************************************函数名称:PutSting功能:向PC机发送字符串参数:无返回值:无********************************************/void PutString(uchar *ptr){while(*ptr != '\0'){while (!(IFG1 & UTXIFG0)); // TX缓存空闲?TXBUF0 = *ptr++; // 发送数据}while (!(IFG1 & UTXIFG0));TXBUF0 = '\n';}/*******************************************函数名称:Delays功能:延时一会参数:无返回值:无********************************************/void Delays(void){uchar i=20;uint j;while(i--){j=2000;while(j--);}}//串口中断响应函数#pragma vector=UART0RX_VECTOR__interrupt void usart0_rx (void){if(49==RXBUF0){_BIC_SR_IRQ(LPM0_bits); // Clear LPM0, SET BREAKPOINT HERE}if(50==RXBUF0){ADC12IE = 0x00; // 关闭ADC}}//USART.H#ifndef __USART0_H#define __USART0_H#include <msp430x14x.h>#define uchar unsigned char#define uint unsigned intextern void Usart0_Init();extern void SentData(uchar num);extern void PutString(uchar *ptr);extern void Delays(void);extern void Sent_Num(uint num);#endif//LCD12864.H#ifndef _LCD12864_H#define _LCD12864_H#include <msp430x14x.h>#define CPU_F ((double)8000000)#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 uchar unsigned char#define uint unsigned int#define ulong unsigned long/*12864应用指令*/#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H#define AC_INIT 0x02 //将AC设置为00H。
MSP430通用串口的应用
第7章通用串口的应用7.1 串行通信的基本知识计算机系统与外部的信息交换称为通信。
通信方式主要有并行与串行两种方式。
并行通信是指通信数据的各数据位在多条线上同时被传输,以字或字节为单位并行进行。
并行通信速度快,但用的通信线多、成本高,故不宜进行远距离通信。
串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。
其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。
根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。
信息只能单向传送为单工;信息能双向传送但不能同时双向传送称为半双工;信息能够同时双向传送则称为全双工。
串行通讯又分为异步通讯和同步通讯两种方式。
同步通信是一种连续串行传送数据的通信方式,一次通信只传送一帧信息。
这里的信息帧与异步通信中的字符帧不同,通常含有若干个数据字符。
它们均由同步字符、数据字符和校验字符(CRC)组成。
其中同步字符位于帧开头,用于确认数据字符的开始。
数据字符在同步字符之后,个数没有限制,由所需传输的数据块长度来决定;校验字符有1到2个,用于接收端对接收到的字符序列进行正确性的校验。
同步通信的缺点是要求发送时钟和接收时钟保持严格的同步。
异步通信中,在异步通信中有两个比较重要的指标:字符帧格式和波特率。
数据通常以字符或者字节为单位组成字符帧传送。
字符帧由发送端逐帧发送,通过传输线被接收设备逐帧接收。
发送端和接收端可以由各自的时钟来控制数据的发送和接收,这两个时钟源彼此独立,互不同步。
接收端检测到传输线上发送过来的低电平逻辑"0"(即字符帧起始位)时,确定发送端已开始发送数据,每当接收端收到字符帧中的停止位时,就知道一帧字符已经发送完毕。
图7.1 MAX232典型连接图最常见的串行通信标准有RS232、RS485、SPI和I2C等。
其中RS232和RS485均是美国电子工业协会EIA(Electronic Industry Association)制定的串行物理接口标准。
430串口通信的资料
1 MSP430单片机I/O端口控制特点与8031单片机相比,MSP430的I/O端口的功能要强大的多,其控制的方法也更为复杂。
MSP430的I/O端口可以实现双向的输入、输出;完成一些特殊功能如:驱动LCD、A/D转换、捕获比较等;实现I/O 各种中断。
MSP430采用了传统的8位端口方式保证其兼容性,即每个I/O端口控制8个I/O引脚。
为了实现对I/O端口每一个引脚的复杂控制,MSP430中的每个I/O口都对应一组8位的控制寄存器(如图1)。
寄存器中的每一位对应一个I/O引脚,实现对该引脚的独立控制。
寄存器的功能和数目是由该I/O口所能完成的功能以及类型确定的。
[2]图1为MSP430的一个I/O端口的控制结构示意图。
对于最基本的只能完成输入、输出功能的I/O端口其控制寄存器只有3个。
其中,输入寄存器保存输入状态;输出寄存器保存输出的状态,方向寄存器控制对应引脚的输入、输出状态。
本文中用来实现I2C总线接口的P6.6、P6.7都属于这类的端口。
此外,有些I/O端口不但可以用作基本的输入输出,而且可以用作其他用途,比如可以作为LCD的驱动控制引脚。
这类端口的控制功能寄存器实现引脚功能状态的切换。
再者,有一类端口不但可以完成上述两种端口的功能,而且可以实现中断功能。
该类端口拥有图1中所有的寄存器,中断触发的方式以及中断的屏蔽性都可以通过相应的寄存器控制。
本文中使用的P2.0就属于该类端口,利用它来接收LM92发出的中断。
通过上述的控制结构,MSP430的I/O端口可以实现很丰富的功能。
不仅如此,其中一些I/O口还可以与MSP430中的特殊模块相结合完成更为复杂的工作。
如与捕获比较模块相结合可以实现串行通信,与A/D 模块结合实现A/D转换等。
此外,MSP430 I/O端口的电器特性也十分突出,几乎所有的I/O口都有20mA 的驱动能力,对于一般的LED、蜂鸣器可以直接驱动无需辅助电路。
许多端口内部都集成了上拉电阻,可以方便与外围器件的接口。
430单片机串口模块详解.pdf
PENV PEV
表 1-1 控制寄存器
SP
CHAR LISTEN SYNC
MM
SWRST
USART 的控制寄存器有 8 个有效控制位,通过对这些控制位的设置可以对工作模 式,通信协议,校验位等进行选择。用户对 USART 的所有操作都是通过操作该寄 存器的控制位来完成的[6]。下面是各个位的简单功能描述,知道这些控制位பைடு நூலகம்功 能,有助于我们在后面进行硬件连接和软件设计.
PENV:校验使能位。该位为 0 不允许校验;为 1 时,允许校验,且 在发送时产生校验位,在接收时希望接收到校验位。在地址位多机 模式中地址位包括在校验计算中。
PEV:奇偶校验位。为 0 时,奇校验,为 1 时进行偶校验。 SP:停止位。接收时停止位只有一个。发送时,该位为 0,只有一个
USCI_Ax 模块支持: UART 模式; IrDA 通信的脉冲整形; LIN 通信的自动波特率检测; SPI 模式; USCI_Bx 模块支持: IIC 模式; SPI 模式;
由于本设计解决的是串口通讯问题,所以通信的基本原理是利用 MSP430 的 串口通讯模块(USART)来实现单片机和 PC 机之间的串口通信。
为同步通信(SPI)模式。 MM:多机模式选择。当该位为 0 时,多机模式选择线路空闲多机协
议;该位为 1 时,多机模式选择地址位多机协议。 SWRST:软件复位使能位。也叫控制位。该位影响着其他控制位和状
态位的状态,在串行口的使用过程中,这一位比较重要。一次正确 的 USART 模块初始化应该是这样的顺序:先在 SWRST=1 的情况下设 置串口;然后设置 SWRST=0;最后如果使用中断,则设置相应的中断 使能。该位为 0 时:USART 模块被允许。该位为 1 时:如果该位置位, 则 USART 状 态 机 和 操 作 运 行 标 志 位 都 被 初 使 化 成 复 位 状 态 (URXIFG=URXIE=UTXIE=0,UTXIFG=1);同时所受影响的逻辑位保持 在复位状态,直到 SWRST 位复位。这意味着,当系统复位后,只有 对 SWRST 位复位,USART 的功能才能被重新允许;但是接收和发送标 志 URXE 和 UTXE 不受 SWRST 控制位的影响。
单片机MSP430与PC机串口通讯设计说明
单片机MSP430与PC机串口通讯设计摘要在多机通信的分布式控制系统中,通过PC机的串口与多台单片机的通信是最方便的。
在这样的分布式控制系统中,单片机与微机之间的多路通信是整个系统的关键。
基于MSP430系列单片机自身优越的性能以与其超低功耗的特点,利用MSP430F149的USART可以实现这种分布式多机通信功能。
在解决了与PC串口或其他带有串口的终端相连所需要的串口电平和逻辑关系的转变之后,选用MSP430F149的异步模式UART,用C语言完成下位机(PC机)接收和发送数据程序,借助VC++6.0开发平台并利用PComm软件包完成上位机(单片机)的通信程序。
文章介绍了美国TI公司新一代16位Flash型MSP430F149系列单片机的结构、特性和功能。
详细介绍了如何利用VC十+6.0进行串口通讯程序的编制,重点介绍了如何利用实现异步通讯的方法。
关键词:MSP430系列单片机,多路通信,控制系统,异步模式,PcommDesign of the Serial Communicationbetween MSP430F149 and PCABSTRACTIn the controlled system of distributing type in which many computers are communicating, by way of the PC string contact with many single chip machines to correspond is the most convenient.In this controlled system of distributing type, the various communication between single chip machines and microcomputer is the whole key. According to the low achievement consume and perfect function of MSP430,The USART that used in system of MSP430F149 can carry out this kind of function of singular to group.It is required to solve the voltage conversionand the change of logic relation, when the MSP430 connects with the PC string or other terminals which take with strings.And then, we can choose the asynchronous module (UART) of MSP430F149 to complete the MSP430F149’s main processor in language of C and write out the PC’s processor asking for help from The VC++6.0 and The Pcomm.This paper introduces the structure, principle and feature of new generation of 16 bit&Flash-type microcontrollerwhich belongs to the Texas Instruments MSP430F149 series. At the same time, it alsointroduces how to carry out the method of theserial communication between PC and MSP430F149. The paper presents how to use VC++6.0 design serial port communicationprogram,especially calling Pcomm functions to control serial port to transfer data.KEY WORDS:MSP430F149single-chip computer, serialcommunication, control system,UART,PComm目录摘要1ABSTRACT2目录3前言4第一章串口通讯的系统组成与原理5§1.1 系统组成与通讯原理5§ 1.1.1 系统构成5§ 1.1.2 通信原理与协议6第二章硬件电路设计11§2.1 接口电平电路设计11§2.1.1 RS-232接口电路设计11§2.2 单片机电路设计14§2.2.1 单片机电路设计图14第三章软件设计16§3.1 功能描述16§3.1.1 上位机和下位机实现的功能16一、功能描述:16§3.2 程序设计16§3.2.1 下位机程序设计16§3.2.2 上位机(PC机)程序设计26结论31参考文献33前言在工业控制领域,由多单片机构成的系统很多,如大规模测控系统、大型车辆控制系统、机器人控制系统等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <msp430x14x。
h〉
char UART1_TX_BUF[60];// 串口1 的发送缓冲区
char UART1_RX_BUF[60];// 串口1 的接收缓冲区
int nTX1_len;
char nRX1_len;
char nRX1_Len_temp;//临时文件
char nTX1_Flag;
int nSend_TX1;
char UART1_RX_Temp[60];
int i;
void Init_UART1(void)
{
U1CTL =0x00;//将寄存器的内容清零
U1CTL &=~SWRST;//SWRDT复位,uart允许
U1CTL += CHAR;//数据位为8bit
U1TCTL |=SSEL0;//波特率发生器选择ACLK
UBR0_1 = 0x03;
UBR1_1 = 0x00;
UMCTL_1 = 0x4A;//使用32khz晶振时,波特率为9600
ME2 |= UTXE1 + URXE1; //使能UART1的TXD和RXD
IE2 |= URXIE1;//使能UART1的RX中断
IE2 |= UTXIE1;//使能UART1的TX中断
P3SEL |= BIT6;//设置P3.6为UART1的TXD
P3SEL |= BIT7;//设置P3.7为UART1的RXD
P3DIR |= BIT6; //P3.6为输出管脚
return;
}
void Init_Port(void)
{
//将所有的管脚在初始化的时候设置为输入方式
P3DIR = 0;
//将所有的管脚设置为一般I/O口
P3SEL = 0;
return;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0x00;//将寄存器的内容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1
//xts=0
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i—-);
}
while ((IFG1 &OFIFG)== OFIFG);// 如果OSCFault =1 //OFIFG振荡器错误
BCSCTL2 = 0x00;//将寄存器的内容清零
BCSCTL2 += SELM1;//MCLK的时钟源为TX2CLK,分频因子为1//10,000000
BCSCTL2 += SELS;//SMCLK的时钟源为TX2CLK,分频因子为1//00001000
}
///////////////////////////////////////
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;// 关闭看门狗
_DINT();// 关闭中断
// 初始化时钟
Init_CLK();
// 初始化端口
Init_Port();
// 初始化串口1
Init_UART1();
// 打开中断
_EINT();
while(1);
}
#pragma vector = UART1RX_VECTOR
__interrupt void UART1_RXISR(void)
{
UART1_RX_BUF[nRX1_Len_temp]=RXBUF1; //将数据读入寄存器。
nRX1_len=nRX1_Len_temp;
for(i = 0;i 〈nRX1_len;i++)
UART1_RX_Temp[i] = UART1_RX_BUF[i];//将接收到的数据拷贝到临时缓冲区。
nTX1_len= nRX1_len+1;
IFG2 |= UTXIFG1;// 设置中断标志,进入发送中断程序
nRX1_len=0;
}
#pragma vector = UART1TX_VECTOR
__interrupt void UART1_TXISR(void)
{
if(nTX1_len != 0)
{
nTX1_Flag = 0;// 表示缓冲区里的数据没有发送完
TXBUF1 = UART1_RX_BUF[nSend_TX1];
nSend_TX1 += 1;
if(nSend_TX1 〉= nTX1_len)
{
nSend_TX1 = 0;
nTX1_len = 0;
nTX1_Flag = 1; //缓冲区里没有数据要发送了
}
nTX1_len=0;
}
}。