void ctrl_Serial(void) //将接收到的字符发送出去 { unsigned char a; while(RI==0); //循环何时结束? RI=0; a=SBUF; SBUF=a; while(TI==0); TI=0; }
时间: 2023-10-16 11:07:19 浏览: 38
这是一段串口通信的发送函数,其功能是将接收到的字符发送出去。代码中的while循环是为了等待接收完成,RI是串口接收完成标志位,当RI为1时,表示已经接收完成,然后将RI清零,并将接收到的字符a存储到SBUF中,接着通过while循环等待发送完成,TI是串口发送完成标志位,当TI为1时,表示发送完成,然后将TI清零。这样就完成了一次串口通信的发送操作。
相关问题
请帮我优化这段代码include <reg52.h> #include <stdio.h> #include <string.h> #define LCD_DATA P0 #define LCD_RS P2_0 #define LCD_RW P2_1 #define LCD_EN P2_2 #define LED_PIN P1_0 #define BUZZER_PIN P1_1 void delay(unsigned int ms); void LCD_init(); void LCD_command(unsigned char cmd); void LCD_data(unsigned char dat); void LCD_string(char *str); void LCD_clear(); void UART_init(); void UART_sendChar(unsigned char ch); void UART_sendString(char *str); unsigned char UART_receiveChar(); void executeCommand(char *command); void main() { char command[20]; UART_init(); LCD_init(); while (1) { if (UART_receiveChar() == ':') { UART_receiveChar(); // Ignore space after ':' fgets(command, sizeof(command), stdin); executeCommand(command); UART_sendString(command); // Send back the received command } } } void delay(unsigned int ms) { unsigned int i, j; for (i = 0; i < ms; i++) for (j = 0; j < 110; j++); } void LCD_init() { LCD_command(0x38); // 2 lines, 5x7 matrix LCD_command(0x0C); // Display on, cursor off LCD_command(0x06); // Increment cursor LCD_command(0x01); // Clear display delay(2); } void LCD_command(unsigned char cmd) { LCD_RS = 0; LCD_RW = 0; LCD_EN = 1; LCD_DATA = cmd; delay(2); LCD_EN = 0; } void LCD_data(unsigned char dat) { LCD_RS = 1; LCD_RW = 0; LCD_EN = 1; LCD_DATA = dat; delay(2); LCD_EN = 0; } void LCD_string(char *str) { while (*str) { LCD_data(*str++); } } void LCD_clear() { LCD_command(0x01); // Clear display delay(2); } void UART_init() { TMOD = 0x20; // Timer1 mode 2: 8-bit auto-reload TH1 = 0xFD; // 9600 baud rate SCON = 0x50; // Serial mode 1: 8-bit data, 1 stop bit, receive enabled TR1 = 1; // Start Timer1 } void UART_sendChar(unsigned char ch) { SBUF = ch; while (TI == 0); // Wait for transmission to complete TI = 0; // Clear transmission flag } void UART_sendString(char *str) { while (*str) { UART_sendChar(*str++); } } unsigned char UART_receiveChar() { while (RI == 0); // Wait for reception to complete RI = 0; // Clear reception flag return SBUF; } void executeCommand(char *command) { if (strncmp(command, "LED on", 6) == 0) { LED_PIN = 1; } else if (strncmp(command, "buzzer on", 9) == 0) { BUZZER_PIN = 1; } else if (strncmp(command, "showstr", 7) == 0) { char *str = command + 8; // Get the string after "showstr" LCD_clear(); LCD_command(0x80); // Move cursor to the beginning of the first line LCD_string(str); } }
这段代码可以进行如下的优化:
1. 将LCD的RS、RW、EN引脚的控制函数封装成一个公共函数,避免代码重复。
2. 可以使用宏定义或枚举类型来定义LED_PIN和BUZZER_PIN,提高代码的可读性。
3. 在executeCommand函数中,可以使用switch-case语句来代替if-else语句,提高代码的可读性。
4. 在UART_receiveChar函数中,可以使用do-while循环来代替while循环,提高代码的可读性。
5. 在executeCommand函数中,可以使用strtok函数来解析命令字符串,提高代码的可读性。
6. 在executeCommand函数中,可以使用strcmp函数来比较字符串,避免使用strncmp函数时出现错误。
7. 在执行LED_PIN = 1或BUZZER_PIN = 1之前,可以先检查这些引脚是否已经被初始化为输出模式,避免出现意外错误。
8. 在executeCommand函数中,可以添加一些错误处理代码,以防止出现错误的命令。
9. 可以添加注释,提高代码的可读性。
下面是优化后的代码:
Keil AT89C51单片机接收串口助手发送的字符串并转化为不超过三位的整数储存在num中,然后将num转化为十六进制输出到两位数码管上的代码
以下是参考代码:
```c
#include <reg51.h>
#define FREQ_OSC 11059200UL // 晶振频率
#define BAUD_RATE 9600 // 串口波特率
sbit D1 = P1^0; // 数码管1
sbit D2 = P1^1; // 数码管2
sbit D3 = P1^2; // 数码管3
unsigned char num = 0; // 存储转化后的整数
unsigned char hex[2] = {0}; // 存储转化后的十六进制数
// 初始化串口
void init_serial()
{
TH1 = TL1 = -(FREQ_OSC/12/32/BAUD_RATE); // 设置波特率
TMOD &= 0x0F; // 清零定时器1模式位
TMOD |= 0x20; // 设定定时器1为模式2
SCON = 0x50; // 串口方式1,允许接收
TR1 = 1; // 启动定时器1
}
// 将字符转化为数字
unsigned char char_to_num(unsigned char ch)
{
if (ch >= '0' && ch <= '9')
return ch - '0';
else
return 0;
}
// 将数字转化为十六进制字符
unsigned char num_to_hex(unsigned char num)
{
if (num < 10)
return num + '0';
else
return num - 10 + 'A';
}
// 将数字转化为不超过三位的整数
void convert_num(unsigned char ch1, unsigned char ch2, unsigned char ch3)
{
unsigned char num1 = char_to_num(ch1);
unsigned char num2 = char_to_num(ch2);
unsigned char num3 = char_to_num(ch3);
num = num1 * 100 + num2 * 10 + num3;
}
// 将数字转化为十六进制数
void convert_hex(unsigned char num)
{
hex[0] = num_to_hex(num/16);
hex[1] = num_to_hex(num%16);
}
// 显示数字
void display_num(unsigned char num)
{
D1 = 1; D2 = 1; D3 = 1; // 关闭所有数码管
if (num < 100)
D1 = 0;
if (num < 10)
D2 = 0;
P2 = num / 100; // 显示百位数码管
P0 = 0xFF; P0 = 0xFE; // 打开数码管1
P2 = (num % 100) / 10; // 显示十位数码管
P0 = 0xFF; P0 = 0xFD; // 打开数码管2
P2 = num % 10; // 显示个位数码管
P0 = 0xFF; P0 = 0xFB; // 打开数码管3
}
// 主函数
void main()
{
init_serial(); // 初始化串口
while (1)
{
if (RI) // 判断是否接收到数据
{
RI = 0; // 清除接收标志位
convert_num(SBUF, SBUF, SBUF); // 将接收到的字符转化为数字
convert_hex(num); // 将数字转化为十六进制
display_num(hex[0]); // 显示十六进制数的高位
display_num(hex[1]); // 显示十六进制数的低位
}
}
}
```
注:以上代码仅供参考,具体实现需要根据硬件环境和实际需求进行适当修改。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)