STM8 UART1 发送乱码,心中千万头草泥马在策马奔腾!求助!

john_liqinghan 2015-01-29 01:18:41
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "stm8s_clk.h"
#include "stm8s_gpio.h"
#include "stm8s_uart1.h"
#include "stm8s.h"

void Init(void);
void Uart1Send8String(u8 *pStr,u8 length);
void delayMs(u32 ms){
u32 count =1000;
for(;ms>0;ms--){
for(;count>0;count--){
_asm("nop");
}
}
}
void Uart1Send8String(u8 *pStr,u8 length){
u8 i;
for(i=0;i<length;i++){
while(UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
UART1_SendData8(*pStr);
delayMs(100);
pStr++;
}
}
void Init(void){
CLK_DeInit();
CLK_HSICmd(ENABLE);
while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY)== RESET);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);//16MHz 8分频为2MHz
CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);

//GPIO初始化
GPIO_DeInit(GPIOD);
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOC);
GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_OD_LOW_FAST); //USART1_TX-PD5
GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT); //USART1_RX-PD6

UART1_DeInit();
UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, \
UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
//UART1_ITConfig(UART1_IT_RXNE, ENABLE);
//UART1_ITConfig(UART1_IT_TXE, ENABLE);
UART1_Cmd(ENABLE);
}

void main(void)
{
Init();
while(1)
Uart1Send8String("abcdef",0x06);
}
...全文
873 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_19764919 2015-11-28
  • 打赏
  • 举报
回复
楼主,你好二,我把你的代码直接输入进去,一点问题没有,害得我没问题还读了一遍你的帖子。发现你居然范了如此低级的错误。
lr2131 2015-02-11
  • 打赏
  • 举报
回复
引用 22 楼 liqinghan 的回复:
[quote=引用 21 楼 yuanruizhang 的回复:] [quote=引用 19 楼 lr2131 的回复:] [quote=引用 18 楼 liqinghan 的回复:] [quote=引用 17 楼 lr2131 的回复:] [quote=引用 16 楼 liqinghan 的回复:] [quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。 [/quote] STM8很明显是TTL电平,TTL<-------> RS232 <--------->电脑 [/quote] 那你用RS232电平转换芯片接到电脑的RS232接口上,或者用CH340这样的TTL转USB的芯片,转USB接到PC上。[/quote] 如果,单片机串口环回测试没有问题,只有可能是串口线和上位机设置的问题了,另外需要确定波特率是否正确,如果波特率设置不对,虽然环回测试正确,发到上位机也会乱码。楼主现在是使用2M的时钟,如果有两块板子可以用不同的时钟,设置同样的波特率来测试波特率是否正确。 PS:我给你的代码是OK的呀,不过我使用的是16M的时钟,那段代码我又重新测试了一遍。[/quote] 谢谢!坑死我的电路设计,不是我设计的电路板,搞死我了,设计者少放了一个232电平转换,直接RX,TX出来就接DB9了。[/quote] 看,被我说中了
john_liqinghan 2015-02-07
  • 打赏
  • 举报
回复
引用 21 楼 yuanruizhang 的回复:
[quote=引用 19 楼 lr2131 的回复:] [quote=引用 18 楼 liqinghan 的回复:] [quote=引用 17 楼 lr2131 的回复:] [quote=引用 16 楼 liqinghan 的回复:] [quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。 [/quote] STM8很明显是TTL电平,TTL<-------> RS232 <--------->电脑 [/quote] 那你用RS232电平转换芯片接到电脑的RS232接口上,或者用CH340这样的TTL转USB的芯片,转USB接到PC上。[/quote] 如果,单片机串口环回测试没有问题,只有可能是串口线和上位机设置的问题了,另外需要确定波特率是否正确,如果波特率设置不对,虽然环回测试正确,发到上位机也会乱码。楼主现在是使用2M的时钟,如果有两块板子可以用不同的时钟,设置同样的波特率来测试波特率是否正确。 PS:我给你的代码是OK的呀,不过我使用的是16M的时钟,那段代码我又重新测试了一遍。[/quote] 谢谢!坑死我的电路设计,不是我设计的电路板,搞死我了,设计者少放了一个232电平转换,直接RX,TX出来就接DB9了。
lr2131 2015-02-05
  • 打赏
  • 举报
回复
引用 18 楼 liqinghan 的回复:
[quote=引用 17 楼 lr2131 的回复:] [quote=引用 16 楼 liqinghan 的回复:] [quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。 [/quote] STM8很明显是TTL电平,TTL<-------> RS232 <--------->电脑 [/quote] 那你用RS232电平转换芯片接到电脑的RS232接口上,或者用CH340这样的TTL转USB的芯片,转USB接到PC上。
john_liqinghan 2015-02-05
  • 打赏
  • 举报
回复
引用 17 楼 lr2131 的回复:
[quote=引用 16 楼 liqinghan 的回复:] [quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。 [/quote] STM8很明显是TTL电平,TTL<-------> RS232 <--------->电脑
Richar_Yuan 2015-02-05
  • 打赏
  • 举报
回复
引用 19 楼 lr2131 的回复:
[quote=引用 18 楼 liqinghan 的回复:] [quote=引用 17 楼 lr2131 的回复:] [quote=引用 16 楼 liqinghan 的回复:] [quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。 [/quote] STM8很明显是TTL电平,TTL<-------> RS232 <--------->电脑 [/quote] 那你用RS232电平转换芯片接到电脑的RS232接口上,或者用CH340这样的TTL转USB的芯片,转USB接到PC上。[/quote] 如果,单片机串口环回测试没有问题,只有可能是串口线和上位机设置的问题了,另外需要确定波特率是否正确,如果波特率设置不对,虽然环回测试正确,发到上位机也会乱码。楼主现在是使用2M的时钟,如果有两块板子可以用不同的时钟,设置同样的波特率来测试波特率是否正确。 PS:我给你的代码是OK的呀,不过我使用的是16M的时钟,那段代码我又重新测试了一遍。
falloutmx 2015-02-05
  • 打赏
  • 举报
回复
乱码?你发0x55和0xaa,电脑那段收到的数据是啥?串口没那么容易被干扰的
lr2131 2015-02-04
  • 打赏
  • 举报
回复
引用 16 楼 liqinghan 的回复:
[quote=引用 15 楼 lr2131 的回复:] 这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了![/quote] 硬件上,你注意你的RX TX出来是TTL电平,还是RS232电平。 之前见有人把单片机的RX TX直接接到电脑串口上(我以前也这么干过) 如果硬件也没问题,那只能是串口设置不对,那就再调波特率,数据位,奇偶校验等等这些设置。
john_liqinghan 2015-02-04
  • 打赏
  • 举报
回复
引用 15 楼 lr2131 的回复:
这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,那就再调波特率,数据位,奇偶校验等等这些设置。
MCU RX TX相连在一起,发送和接收到的数据都是对的,但是断开,用串口工具连接电脑显示就不对了,不知道是啥原因了!
john_liqinghan 2015-02-03
  • 打赏
  • 举报
回复
引用 12 楼 yuanruizhang 的回复:
发送0xaa在示波器上看是0101 0101是没有错的, 串口发送数据是先发送起始位在发送bit0 1 2 3.... 最后发送bit7 bit7后面跟停止位,下面是我自己的串口代码,测试过是没有问题,楼主可以修改试试! #include"stm8s103f3p.h" /*================================================== 函数名:UART_INIT 函数功能:完成串口初始化,波特率位9600 入口参数:无 返回值: 无 =================================================*/ void UATR_INIT(void) { UART1_CR1=0x00; UART1_CR2=0x00; UART1_CR3=0x00; // (1) 必须先写BRR2 // (2) BRR1存放的是分频系数的第11位到第4位, // (3) BRR2存放的是分频系数的第15位到第12位,和第3位 // 分频系数=2M/9600=208 // 对应的十六进制数为00d0,BBR1=0d,BBR2=00 // 分频系数=16M/9600=1666 // 对应的十六进制数为0683,BBR1=68,BBR2=03 UART1_BRR2=0x03; UART1_BRR1=0x68; UART1_CR2=0x2c; //允许接收,发送,开接收中断 } /*================================================== 函数名:UART_Send 函数功能:向串口发送单个字符 入口参数:ch 返回值: 无 =================================================*/ void UART_Send(BYTE ch) { while((UART1_SR & 0x80)==0x00); UART1_DR=ch; } /*================================================== 函数名:UART_Sendstring 函数功能:向串口发送字符串 入口参数:*str 返回值: 无 =================================================*/ void UART_sendstring(BYTE *str) { while(*str!= '\0') //判断字符串是否发送完毕 { UART_Send(*str); //发送单个字符 str++; //字符地址加1,指向先下一符 } } /*================================================== 函数名:UART_Senddata 函数功能:向串口发送字符数据 入口参数:data 返回值: 无 =================================================*/ void UART_senddata(BYTE data) { BYTE temp[3]; temp[0]=data %10; temp[1]=data%100/10; temp[2]=data/100; UART_Send(temp[2]+48); UART_Send(temp[1]+48); UART_Send(temp[0]+48); } /*================================================== 函数名:UART_Senddata 函数功能:向串口发送32位数据。 入口参数:data 返回值: 无 =================================================*/ void UART_Send32data(DWORD data) { BYTE temp[3]; DWORD temp1; temp1=data; temp[0]=temp1|0x0; UART_senddata(temp[0]); UART_Send(' '); temp1 >>= 8; temp[1]=temp1|0x0; UART_senddata(temp[1]); UART_Send(' '); temp1 >>= 8; temp[2]=temp1|0x0; UART_senddata(temp[2]); UART_Send(' '); }
试过了,结果还是一样的。。。
lr2131 2015-02-03
  • 打赏
  • 举报
回复
这种通信的问题,LZ你应该先做回环检查,先甩来通信设置的问题,直接测试底层驱动代码的问题,如果自己发自己收都不对,那就说明是驱动有问题,找找时钟设置,UART的寄存器设置等等这些。‘ 能自己发自己收没问题,那就再调波特率,数据位,奇偶校验等等这些设置。
john_liqinghan 2015-02-03
  • 打赏
  • 举报
回复
妈蛋!使用了各种方法,scomm显示的还是乱码!,调试后发现各种寄存器的值都是正常的,现在我不得不怀疑 STM8S0003F3P6的 内部时钟能否用来的做串口的时钟源,又或者是电路的干扰!靠近STm8附近有一颗仅在 和一个大电容以及电感!这尼玛的设计的电路,要搞死人的!
Richar_Yuan 2015-01-31
  • 打赏
  • 举报
回复
发送0xaa在示波器上看是0101 0101是没有错的, 串口发送数据是先发送起始位在发送bit0 1 2 3.... 最后发送bit7 bit7后面跟停止位,下面是我自己的串口代码,测试过是没有问题,楼主可以修改试试! #include"stm8s103f3p.h" /*================================================== 函数名:UART_INIT 函数功能:完成串口初始化,波特率位9600 入口参数:无 返回值: 无 =================================================*/ void UATR_INIT(void) { UART1_CR1=0x00; UART1_CR2=0x00; UART1_CR3=0x00; // (1) 必须先写BRR2 // (2) BRR1存放的是分频系数的第11位到第4位, // (3) BRR2存放的是分频系数的第15位到第12位,和第3位 // 分频系数=2M/9600=208 // 对应的十六进制数为00d0,BBR1=0d,BBR2=00 // 分频系数=16M/9600=1666 // 对应的十六进制数为0683,BBR1=68,BBR2=03 UART1_BRR2=0x03; UART1_BRR1=0x68; UART1_CR2=0x2c; //允许接收,发送,开接收中断 } /*================================================== 函数名:UART_Send 函数功能:向串口发送单个字符 入口参数:ch 返回值: 无 =================================================*/ void UART_Send(BYTE ch) { while((UART1_SR & 0x80)==0x00); UART1_DR=ch; } /*================================================== 函数名:UART_Sendstring 函数功能:向串口发送字符串 入口参数:*str 返回值: 无 =================================================*/ void UART_sendstring(BYTE *str) { while(*str!= '\0') //判断字符串是否发送完毕 { UART_Send(*str); //发送单个字符 str++; //字符地址加1,指向先下一符 } } /*================================================== 函数名:UART_Senddata 函数功能:向串口发送字符数据 入口参数:data 返回值: 无 =================================================*/ void UART_senddata(BYTE data) { BYTE temp[3]; temp[0]=data %10; temp[1]=data%100/10; temp[2]=data/100; UART_Send(temp[2]+48); UART_Send(temp[1]+48); UART_Send(temp[0]+48); } /*================================================== 函数名:UART_Senddata 函数功能:向串口发送32位数据。 入口参数:data 返回值: 无 =================================================*/ void UART_Send32data(DWORD data) { BYTE temp[3]; DWORD temp1; temp1=data; temp[0]=temp1|0x0; UART_senddata(temp[0]); UART_Send(' '); temp1 >>= 8; temp[1]=temp1|0x0; UART_senddata(temp[1]); UART_Send(' '); temp1 >>= 8; temp[2]=temp1|0x0; UART_senddata(temp[2]); UART_Send(' '); }
john_liqinghan 2015-01-30
  • 打赏
  • 举报
回复
一张调试图
john_liqinghan 2015-01-30
  • 打赏
  • 举报
回复
引用 5 楼 xqhrs232 的回复:
这个是STM8的代码?怎么觉得像STM32的啊!STM8也玩ST提供的库函数?
ST的东西,用它的库比较方便,速度快一点,不用自己去计算寄存器。
john_liqinghan 2015-01-30
  • 打赏
  • 举报
回复
引用 4 楼 changqing1990 的回复:
用示波器量一下,一切都清楚了!
测量TX吧?
xqhrs232 2015-01-30
  • 打赏
  • 举报
回复
这个是STM8的代码?怎么觉得像STM32的啊!STM8也玩ST提供的库函数?
CH_Qing 2015-01-30
  • 打赏
  • 举报
回复
用示波器量一下,一切都清楚了!
john_liqinghan 2015-01-30
  • 打赏
  • 举报
回复
串口发送的是:
0xAA
得到如下图像:




感觉是倒过来!
数据颠倒了,示波器
0xaa 显示 start bit 0 1 0 1 0 1 0 1 stopbit
john_liqinghan 2015-01-30
  • 打赏
  • 举报
回复
引用 4 楼 changqing1990 的回复:
用示波器量一下,一切都清楚了!
数据颠倒了,0xaa 示波器显示 start bit 0 1 0 1 0 1 0 1 stopbit 而 0x55 显示start bit 1 0 1 0 1 0 1 0 stopbit
引用 9 楼 yuanruizhang 的回复:
一直用寄存器方式,没有用过stm8的库,手工计算2M时BRR的值,在看看实际运行中BRR值是否和理论一致了,乱码一般都是波特率出错了。不过还有种情况是串口有问题,前段时间调stm32,调着调着串口就乱码了,搞了1天多,换了根线就ok了,想必楼主不会像我这么倒霉了。
不用库函数我也做了一个程序,单步调试,串口波特率也算对了,数据位,停止位这种都对照了一遍寄存器,没有错误! 但还是一样乱码,你说线有问题,这个我得查查。可我用示波器测也是不对的。
加载更多回复(4)

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧