It's five months since the last hair
Paste the code. UART is the most commonly used serial communication mode. Each single chip microcomputer must bring at least one UART for communication, and CC2530 is no exception. Of course, the CC2530 is a Usart, that is, a universal synchronous asynchronous serial receiver transmitter, which can use asynchronous UART mode or synchronous SPI mode.
Code and analysis
#include <ioCC2530.h> #include "string.h" /**************************** This example simply uses the Usart module of CC2530. After power on, it will automatically send a text through Uart. The number "1" is sent when KET1 is pressed. Send the number "0" to CC2530 in the serial port assistant, and the on-board LED1 will change the state. ****************************/ #define LED1 P1_0 / / LED1 is defined as P10 port control #define KEY1 P0_1 / / define key1 as P01 port control #define uchar unsigned char #define uint unsigned int /*Local function*/ void initUART(void); void initLED(void); void sendmsg(char *); void delay(int n); char temp=0; int main(void) { /*Initialize LED*/ initLED(); /*Initialize Uart*/ initUART(); sendmsg("New crown, new crown, leave!\r\n\r\n"); while(1) { /*Uart Send relevant code snippets*/ if(KEY1 == 0) //If a key is pressed { delay(40); //Delay to eliminate chattering if(KEY1 == 0) { sendmsg("1\r\n"); //The number 1 is sent when the key 1 is detected to be pressed } } /*Uart Accept relevant code snippets*/ if(0 != temp) //If Uart receives data { if(temp == 0x30) //If you receive the number 0 { LED1 = !LED1; //Change LED1 status } temp = 0; //Clear temp } } } #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) { URX0IF = 0; //Clear interrupt flag bit temp = U0DBUF; //Store the 8-bit data of the receive buffer into temp } void initLED(void) { P1DIR |= 0x03; //P1_0/P1_1 is defined as output LED1 = 1; //LED1 lamp is initialized to off } void initUART(void) { P0SEL |= 0x0C; //Port 0_ 4/0_ 5 set as peripheral function U0GCR |= 11; U0BAUD |= 216; //Set the baud rate to 57600 U0CSR |= 0XC0; //Set USART to the Uart function and enable the USART receiver URX0IF = 0; //Clear receive interrupt flag bit EA = 1; //Turn on the main interrupt switch to use the interrupt function of the system URX0IE = 1; //Usart0 interrupt function enable } /*Delay Functions */ void delay(int n) { int i,j; for(i=0;i<n;i++) for(j=0;j<1000;j++); } /*Uart Send function*/ void sendmsg(char *data) { while(1) { if('\0' == *data) //Once the end of the string is detected, it exits. A string always ends with '\ 0' { break; } U0DBUF = *data++; //Otherwise, the current character is passed into the send buffer while(UTX0IF == 0); //Wait for the transmission to complete. After the transmission, UTX0IF will be automatically set to 1 by the system UTX0IF = 0; //Clear send completion status } }
Another version
Of course, there is a version with more code, which I checked when I was experimenting. DMA and FSM are used. Record it 😑, I'm too lazy to play 😬.
#include <ioCC2530.h> #include "string.h" /**************************** This example uses Usart and DMA. The data received by Uart is directly put into the array through DMA without CPU intervention. A text will be sent after power on. A packet structure is defined, with a total of five bits. The frame header is 0x0F,0x0D, then the packet length is 0x34, and then the data bits, 0x30 Turn off the light, 0x31 turn on the light, 0x37 switch the light state, and the last is the check bit, the XOR and sum of the first four bytes. After sending the five bit data in hexadecimal without line break, CC2530 will continue to judge or output verification error according to the result of checksum, After passing the verification, the FSM will verify the first three bytes. After successful verification, the lamp state will be switched, otherwise an error message will be output. ****************************/ #define LED1 P1_0 #define LED2 P1_1 #define KEY1 P0_1 #define uchar unsigned char #define uint unsigned int #pragma bitfields=reversed / / convert to small end mode typedef struct { uchar SRCADDRH; // High 8 bits of source address uchar SRCADDRL; // Lower 8 bits of source address uchar DESTADDRH; // 8 bits higher than the destination address uchar DESTADDRL; // Lower 8 bits of destination address uchar VLEN :3;// Length field mode selection uchar LENH :5;// Transmission length high byte uchar LENL :8;// Transmission length low byte uchar WORDSIZE :1;// Byte or word transfer uchar TMODE :2;// Transmission mode selection uchar TRIG :5;// Trigger event selection uchar SRCINC :2;// Source address increment: - 1 / 0 / 1 / 2 uchar DESTINC :2;// Destination address increment: - 1 / 0 / 1 / 2 uchar IRQMASK :1;// Interrupt mask uchar M8 :1;// 7 or 8bit transmission length, applicable only in byte transmission mode uchar PRIORITY :2;// priority }DMA_DESC; #pragma bitfields = default / / switch back to big end mode DMA_DESC uartdma; //DMA configuration parameter structure variable void initUART(void); void initLED(void); void sendmsg(char *); void receivemsg(void); void delay(int n); uint FSM(uchar *buff); void changeled(uchar data); uint xor(uchar *data); void init_DMA(); uint count = 0; char temp=0; uchar buff[6]; // You need to add one more byte as the terminator, otherwise an error will occur //The starting field is defined as 0x0F 0x0D, and the package length is 4 bytes. The command code is: 1 for on, 0 for off, 7 for switching lamp status, and FCS for the first four bytes of XOR and #define STATE1 0x00 #define STATE2 0x02 #define STATE3 0x04 #define STATE4 0x06 #define STATE5 0x08 int main(void) { initLED(); init_DMA(); initUART(); sendmsg("New crown, new crown, leave!\r\n\r\n"); while(1) { DMAARM |= 0x01; //Put DMA channel 0 into operation DMAIRQ |= 0x00; //Clear DMA transfer completion flag delay(500); if(buff[4] != 0) //If there are already five bits of data in the buff { buff[5]='\0'; sendmsg("The received packets are as follows:"); sendmsg(buff); sendmsg("\r\n"); if(xor(buff) == 1) { if(FSM(buff) == 1) { sendmsg("The received packet is valid\r\n"); } else { sendmsg("Invalid received packet\r\n"); } } else { sendmsg("FCS error"); } memset(buff,0,6); } } } #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) { URX0IF = 0; temp = U0DBUF; } void initLED(void) { P1DIR |= 0x03; LED1 = 1; LED2 = 1; } void initUART(void)//9600 { P0SEL |= 0x0C; U0GCR |= 11; U0BAUD |= 216; U0CSR |= 0XC0; UTX0IF = 0; URX0IF = 0; EA = 1; URX0IE = 1; } void delay(int n)//11us { int i,j; for(i=0;i<n;i++) for(j=0;j<1000;j++); } void sendmsg(char *data) { while(1) { if(*data=='\0') break; U0DBUF = *data++; while(UTX0IF == 0); UTX0IF = 0; } } uint FSM(uchar *buff) { uchar state = STATE1; uchar data; uint flag = 0; while(1) { data = *buff++; switch(state) { case STATE1: if(data == 0x0F) { state = STATE2; } else flag = 1; break; case STATE2: if(data == 0x0D) { state = STATE3; } else flag = 1; break; case STATE3: if(data == 0x34) { state = STATE4; } else flag = 1; break; case STATE4: changeled(data); state = STATE5; break; default: break; } if(state == STATE5) { return 1; } if(flag == 1) { break; } } return 0; } void changeled(uchar data) { if(data == 0x30) LED1 = 1; if(data == 0x31) LED1 = 0; if(data == 0x37) LED1 = !LED1; } /*check*/ uint xor(uchar *data) { uchar temp = 0; /*XOR sum*/ for(int i=0;i<4;i++) { temp ^= *data++; } sendmsg("FCS: "); //Print XOR and view sendmsg(&temp); sendmsg("\r\n"); // sendmsg(&(*data)); if(temp == *data) return 1; else return 0; } void init_DMA() { /*Configure source address*/ uartdma.SRCADDRH=(uchar)((uint)&X_U0DBUF>>8); uartdma.SRCADDRL=(uchar)((uint)&X_U0DBUF&0x00ff); /*Configure destination address*/ uartdma.DESTADDRH=(uchar)((uint)&buff >> 8); uartdma.DESTADDRL=(uchar)((uint)&buff&0x00FF); /*Select LEN as the transfer length*/ uartdma.VLEN=0x00; //Select LEN as the transfer length /*Set transmission length*/ uartdma.LENH=0; uartdma.LENL=5; uartdma.WORDSIZE=0x00; //Select byte transfer uartdma.TMODE=0x00; //Byte mode uartdma.TRIG=14; //Serial port receiving interrupt trigger uartdma.SRCINC=0x00; //Source address increment is 0 uartdma.DESTINC=0x01; //The destination address is incremented by 1 uartdma.IRQMASK=0; //Clear DMA interrupt uartdma.M8=0x00; //Select 8-bit long bytes to transmit data uartdma.PRIORITY=0x02; //Transmission priority is high /*Assign the first address of the configuration structure to the relevant SFR*/ DMA0CFGH=(uchar)((uint)&uartdma >> 8); DMA0CFGL=(uchar)((uint)&uartdma & 0x00ff); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); }
- Learn about Usart of CC2530.
- In line 72, first set the port corresponding to Usart 0 as a peripheral port. Usart is a peripheral. Only when it is set as a peripheral port can Usart send and receive data through Uart;
- Lines 73-74, set the baud rate of Uart, as long as the data in the figure below are written into the register one by one, which is very simple. However, it should be noted that the default system clock of CC2530 in my hand is 16M. The following figure is the corresponding value of 32M baud rate register. Remember to be careful here. If your MCU system clock is 32M, you can write the register directly into the table. If it is 16M, like mine, the value of the register corresponding to baud rate in the following figure is written in, The actual baud rate will be halved. For example, if 115200 baud rate is selected, the corresponding U0GCR is 11 and U0BAUD is 216. After this is written in, the actual baud rate is 57600 under the 16M system clock. If the setting error will lead to garbled code, be careful.
- Line 75, set Usart to Uart mode and enable reception.
- Lines 77-79, open the interrupt related registers, including the total interrupt and the accept interrupt of Uart0. Of course, lines 78-79 can also directly IEN0 |= 0x84;
There's nothing else to say. The general effect is like this. When powered on and sent once, the key will send 1, and replying to 0 will make the LED take the reverse state.
Summary
Uart is really commonly used. I have been practicing for a long time. In fact, although the company also uses protocols such as CAN, SPI and IIC, Uart is still the most commonly used, convenient and simple one. It's important to know about Uart. For the DMA used in the above complex point, let's put it down for the second time. DMA is still very good.