我的上电时钟初始化代码,不知道为什么这样设置波特率115200一直输出不正确。 void OSC_Init(void) { CLKCON &= ~0x40; while(SLEEP&0x40); CLKCON &= ~0x41; } void Usart0_Init(void) { IEN0&=0x7f; PERCFG&=0xfe; P0SEL=0x0c; //P0.2-P0.3为外设,其余为通用io P2DIR&= ~0XC0; U0CSR=0x80; U0UCR=0x00; U0GCR=0x20; U0GCR|=0x0c; //115200 U0BAUD=216; UTX0IF=0; URX0IF=0; URX0IE=1; EA=1; } 请问怎么设置时钟,或者是我串口0初始化设置错了吗?产品cc2511
时间: 2023-08-04 17:02:39 浏览: 126
您的串口初始化代码看起来没有问题,但是可能是时钟初始化设置有误导致串口输出不正确。您可以尝试在时钟初始化代码中增加对系统时钟频率的设置,例如:
```
void OSC_Init(void) {
// 设置系统时钟频率为 24MHz
CLKCON = (CLKCON & ~0x07) | 0x00;
// 等待时钟稳定
while(!(CLKCON & 0x40));
// 设置时钟源为内部高速振荡器
CLKCON &= ~0x41;
}
```
另外,您可以检查一下您的调试工具或终端软件是否设置正确了波特率为115200。如果还是无法解决问题,您可以尝试降低波特率,例如9600或19200,看看是否能够正常输出。
相关问题
在MCS-51系列单片机中,如何通过C语言编程设置定时器T1来实现特定波特率的串行通信?请提供详细的设置步骤和示例代码。
对于MCS-51系列单片机来说,定时器T1是实现串行通信中波特率控制的关键组件。为了帮助你实现特定波特率的串行通信,建议参考以下资料:《掌握单片机C语言编程:波特率计算详解》。这份资源详细阐述了如何根据不同的工作模式来计算和设置波特率,直接关联到你当前的问题。
参考资源链接:[掌握单片机C语言编程:波特率计算详解](https://wenku.csdn.net/doc/648ucagskb?spm=1055.2569.3001.10343)
在MCS-51单片机中,定时器T1可以工作在四种模式下:方式0(13位定时器/计数器)、方式1(16位定时器/计数器)、方式2(8位自动重装载定时器/计数器)和方式3(分裂定时器模式)。为了生成特定的波特率,你首先需要根据系统时钟和预期的波特率计算定时器的初值。
假设系统时钟为11.0592MHz,我们想要设置波特率为9600bps,我们可以选择工作在方式2,因为这种方式可以自动重装初值,简化了编程。
以下是设置定时器T1为方式2并计算初值的示例代码:
```c
#include <reg51.h> // 包含51单片机寄存器定义
// 假设系统时钟为11.0592MHz
#define TIMER_RELOAD_VALUE (256 - (OSC_FREQ / (12 * 32 * BAUD_RATE)))
void Timer1_Init() {
TMOD &= 0x0F; // 清除T1的控制位
TMOD |= 0x20; // 设置T1为方式2
TH1 = TIMER_RELOAD_VALUE; // 装载初值
TL1 = TIMER_RELOAD_VALUE; // 装载初值
TR1 = 1; // 启动定时器T1
}
void main() {
Timer1_Init(); // 初始化定时器T1
SCON = 0x50; // 设置串口为模式1,允许接收
// 其他代码...
}
```
在这段代码中,我们首先包含了MCS-51单片机的寄存器定义文件,然后计算了定时器T1的重装初值,并通过修改TMOD寄存器设置了定时器T1为方式2。接着,我们设置了TH1和TL1寄存器,最后启动了定时器T1。注意,波特率计算中通常包括了12的因子,这是因为单片机的机器周期是12个振荡周期。
掌握这些知识后,你可以根据不同的时钟频率和波特率需求调整TIMER_RELOAD_VALUE的计算方式,从而灵活设置波特率。如果你希望进一步了解定时器的不同工作方式以及它们在实际通信中的应用,建议深入阅读《掌握单片机C语言编程:波特率计算详解》。该资料不仅帮助你解决了当前问题,还将为你提供更多的单片机编程知识和技巧。
参考资源链接:[掌握单片机C语言编程:波特率计算详解](https://wenku.csdn.net/doc/648ucagskb?spm=1055.2569.3001.10343)
在keil上实现stc89c52RC单片机如何接收来自串口发送来的数据并显示在lcd1602上的c语言完整代码
以下是一个简单的例子,演示如何在Keil上使用STC89C52RC单片机接收串口数据并将其显示在LCD1602上。
```c
#include <REG52.H>
#include <stdio.h>
#include <string.h>
#define BAUDRATE 9600 // 波特率
#define FREQ_OSC 11059200UL // 晶振频率
#define TIMER_1_PRESCALER 12 // 定时器1分频系数
#define TIMER_1_RELOAD ((65536 - (FREQ_OSC / (BAUDRATE * TIMER_1_PRESCALER))) >> 8) // 定时器1重装值
#define TIMER_1_RELOAD_LOWBYTE (65536 - (FREQ_OSC / (BAUDRATE * TIMER_1_PRESCALER))) // 定时器1重装值低字节
sbit RS = P2^6; // LCD1602引脚定义
sbit RW = P2^5;
sbit EN = P2^7;
void lcd_init(void);
void lcd_write_data(unsigned char dat);
void lcd_write_cmd(unsigned char cmd);
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *str);
void serial_init(void);
void serial_send(unsigned char dat);
unsigned char serial_receive(void);
void delay_ms(unsigned int ms);
void main()
{
unsigned char str[16];
unsigned char ch;
unsigned char i = 0;
lcd_init();
serial_init();
while(1)
{
ch = serial_receive(); // 接收串口数据
str[i++] = ch;
if(ch == '\n') // 如果接收到换行符,则将接收到的字符串显示在LCD上
{
str[i-1] = '\0';
lcd_show_string(0, 0, str);
i = 0;
}
}
}
void lcd_init(void)
{
lcd_write_cmd(0x38); // 初始化8位双行显示模式
lcd_write_cmd(0x0c); // 开启显示,关闭光标
lcd_write_cmd(0x06); // 设定输入方式为移动光标,不移动屏幕
lcd_write_cmd(0x01); // 清屏
}
void lcd_write_data(unsigned char dat)
{
RS = 1;
RW = 0;
P0 = dat;
EN = 1;
delay_ms(5);
EN = 0;
}
void lcd_write_cmd(unsigned char cmd)
{
RS = 0;
RW = 0;
P0 = cmd;
EN = 1;
delay_ms(5);
EN = 0;
}
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *str)
{
unsigned char addr;
if(y == 0)
addr = 0x80 + x;
else
addr = 0xc0 + x;
lcd_write_cmd(addr);
while(*str)
lcd_write_data(*str++);
}
void serial_init(void)
{
TMOD = 0x20; // 定时器1工作在方式2(8位自动重装),定时器0停止计数
TH1 = TIMER_1_RELOAD;
TL1 = TIMER_1_RELOAD_LOWBYTE;
PCON = 0x00; // 波特率不加倍
SCON = 0x50; // 串口工作在模式1(8位数据,可变波特率)
TR1 = 1; // 启动定时器1
ES = 1; // 打开串口中断
EA = 1; // 打开总中断
}
void serial_send(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
unsigned char serial_receive(void)
{
unsigned char dat;
while(!RI);
dat = SBUF;
RI = 0;
return dat;
}
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i=0; i<ms; i++)
for(j=0; j<120; j++);
}
void serial_isr() interrupt 4
{
if(RI)
RI = 0;
}
```
在这个例子中,我们使用了定时器1来生成波特率时钟,并且使用了串口中断来接收数据。当接收到换行符时,我们将接收到的字符串显示在LCD上。你需要根据自己的需求修改引脚定义和波特率。
阅读全文