C8051F02x串口通信程序

shichaog 2011-05-03 03:55:29
程序如下:
//外部晶振24MHz 波特率115200
#include "c8051f020.h"
#include "stdio.h"
#include "string.h"

#define INBUF_LEN 4 //数据长度

unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag= 0 ;


void init_serialcomm( void )
{ CKCON = 0x30;
SCON0 = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80 ; //SMOD=1;
TH1 = 0xF4 ; //Baud:115200 fosc=24MHz
IE |= 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
// TI=1;

// 这里我没有EIE1 ,这个是有何用????//用于扩着呢中断,是为SPI用的
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
SBUF0=ch;
while (TI0== 0 );
TI0= 0 ;
}

//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do
{
send_char_com(*(str + k));
k++;
}
while (k < strlen);
}


//串口接收中断函数
void serial () interrupt 4 using 3
{
if (RI0)
{
unsigned char ch;
RI0 = 0 ;
ch=SBUF0;
if (ch> 127 )
{
count3= 0 ;
inbuf1[count3]=ch;
checksum= ch- 128 ;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if ( (count3==(INBUF_LEN- 1 )) && (!checksum) )
{
read_flag= 1 ; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
}
}
}
}

void main(void)
{
//c8051f020 initial
//禁止看门狗
WDTCN = 0xDE;
WDTCN = 0xAD;
//设置并选用外部晶振
OSCXCN = 0x67;
while(OSCXCN & 0x80 ==0);
OSCICN |= 0x08;
//Crossbar配置 XBR0.2为串口配置引脚,配置1有效,端口状态由数字外设决定;未配置(0)将作为通用I/O使用,可以读写相应端口寄存器
XBR0 = 0x04; //串口映射到P0.0,TX0;P0.1 RX0
XBR1 = 0;
XBR2 = 0x46; //7 6 5 4 3 2 1 0
// ENABLE crossbar

// P0.0 - TX0 (UART0), Push-Pull, Digital
// P0.1 - RX0 (UART0), Open-Drain, Digital
// P0.2 - Unassigned, Open-Drain, Digital
// P0.3 - Unassigned, Open-Drain, Digital
// P0.4 - Unassigned, Open-Drain, Digital
// P0.5 - Unassigned, Open-Drain, Digital
// P0.6 - Unassigned, Open-Drain, Digital
// P0.7 - Unassigned, Open-Drain, Digital

//输出驱动方式配置
P0MDOUT = 0x01;
// P1MDOUT = 0xFF;
// P2MDOUT = 0xFF;
//P3MDOUT = 0xFF;
//EMIF配置 EMI0CF = 0x1C;
//EMI0TC = 0xFF;

init_serialcomm(); //初始化串口
while ( 1 )
{
if (read_flag) //如果取数标志已置位,就将读到的数从串口发出
{
read_flag= 0 ; //取数标志清0
send_string_com(inbuf1,INBUF_LEN);
}
}

}

基本现状:
程序可以调通,正确生成Hex文件。
用串口通信调试助手,端口可以检测到,数据发送出去,但是收不到。

问题:
如果您手边有这种板子,请麻烦用上面源码,检测程序的正确性,如果有问题,请指出问题所在,并给出调试方法和改正方法。

备注:
如有不明,请留言。







...全文
348 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
palleexu 2012-12-19
  • 打赏
  • 举报
回复
出了问题一般都先从硬件上找原因,确定硬件设计无问题再看软件,要不很折腾人的。
lr2131 2012-12-19
  • 打赏
  • 举报
回复
加跟线?公地线?
fsafjlsdjflks 2012-12-16
  • 打赏
  • 举报
回复
right~
shichaog 2011-05-12
  • 打赏
  • 举报
回复
谢谢各位已解决,是线乱了的问题,之间再加一个线就可以了
trent5145 2011-05-06
  • 打赏
  • 举报
回复
看看官方的程序吧
O丸子爹O 2011-05-05
  • 打赏
  • 举报
回复
给你一个我写的正在用的代码,很好用,用的是中断方式发送数据,不过是用汇编写的,您老就将就着吧,也许有帮助。

外部晶振:22.1184MHz。
ORG 0000H
JMP START ; 主程序入口.
;--------------------------------------------------------------------------
ORG 00A3H
; JMP ISR_UART1 ; UART1中断服务子程(与外界通讯).
ANL EIE2, #0BFH ; 禁止UART1中断.
PUSH DPH
PUSH DPL
PUSH PSW
PUSH ACC
MOV A, SCON1
MOV C, ACC.0
MOV F0, C ; 接收中断标志(D0).
MOV C, ACC.1
MOV F1, C ; 发送中断标志(D1).

JNB F0, NoRx1 ; 判断是否有数据进来.
ANL SCON1, #0FEH ; 此时有数据, 先清除接收中断标志.
MOV A, SBUF1 ; 读出数据到[A].
NoRx1:
JNB F1, NoTx1
ANL SCON1, #0FDH ; 清除发送中断标志.
JNB bUART1CanSend, NoTx1 ; 判断是否能发送串口数据.
MOV A, UART1TxNo
CJNE A, UART1TxTotal, ISR_UART1_1
CLR bUART1CanSend
MOV UART1TxNo, #00H ; 发送数据个数归零.
SJMP NoTx1
ISR_UART1_1:
MOV DPTR, #UART1TxBuf ; 得到发送的起始地址.
MOV DPL, A ; 得到字符的具体位置.
MOVX A, @DPTR ; 取出字符.
MOV SBUF1, A ; 发送字符.
INC UART1TxNo ; 发送个数增加1.
NoTx1:
POP ACC
POP PSW
POP DPL
POP DPH
ORL EIE2, #40H ; 允许UART1中断.
RETI
;--------------------------------------------------------------------------
ORG 0100H
START:
MOV SP, #30H
ACALL InitCPU

MOV DPTR, #StrGPSCmd1
MOV UART0TxAddrL, DPL
MOV UART0TxAddrH, DPH
MOV UART0TxTotal, #SizeGPSCmd1
MOV UART0TxNo, #00H ; 设置发送的个数为0.
CLR bGPSRespone ; 清除标志.
SETB bUART0CanSend ; 可以发送数据.
MOV UART0RxNo, #00H ; 将接收的数据个数清零.
SETB TI0 ; 强制进入发送中断.

;--------------------------------------------------------------------------
InitCPU:
CLR EA ; 禁止中断.
MOV WDTCN, #07H ; 赶跑看门狗.
MOV WDTCN, #0DEH
MOV WDTCN, #0ADH
MOV OSCXCN, #20H ; 外部震荡器控制寄存器.
MOV OSCICN, #8BH ; 内部震荡器控制寄存器.
; 定义交叉开关.
CLR A
MOV XBR0, #04H
MOV XBR1, #14H
MOV XBR2, #0C4H
; 端口输出方式配置.
MOV P0MDOUT, #05H ; 03Enable UART TX and /rd,/wr as push-pull.
MOV P1MDOUT, #0FFH ; 悬空不用.
MOV P2MDOUT, #0DFH ; P2.5悬空, 其余输出.
MOV P3MDOUT, A
MOV P74OUT, #0FFH
MOV P1MDIN, #0FFH ; 悬空不用.
MOV EMI0CF, #3BH ; 配置外部存储器.
MOV REF0CN, #07H ; Reference Control Register.
MOV AMX0CF, A ; AMUX Configuration Register
MOV AMX0SL, A ; AMUX Channel Select Register
MOV ADC0CF, #58H ; ADC Configuraion Register
MOV ADC0CN, #80H ; ADC Control Register
MOV ADC0LTH, A ; ADC Less-Than High Byte Register
MOV ADC0LTL, A ; ADC Less-Than Low Byte Register
MOV ADC0GTH, #0FFH ; ADC Greater-Than High Byte Register
MOV ADC0GTL, #0FFH ; ADC Greater-Than Low Byte Register
; 初始化定时器0.
MOV CKCON, #20H ; Timer2使用系统时钟(22.1184MHz).
; Timer0使用系统时钟的12分频, 即1.8432MHz.
MOV PCON, A
MOV TMOD, #01H ; Timer Mode Register.
MOV TCON, #10H ; Timer Control Register.
MOV TH0, #6FH ; Timer0 High Byte. 20ms计时器.
MOV TL0, #0FFH ; Timer0 Low Byte.
SETB TR0 ; 允许Timer0中断.
SETB ET0 ; T0中断允许.
; 设置UART0(与GPS通讯).
MOV SCON0, #50H ; 允许RI0/TI0中断.
MOV SADDR0, A
MOV SADEN0, A
SETB ES0 ; UART0中断允许.
; 初始化Timer2作为UART0的波特率发生器.
MOV RCAP2H, #0FFH ; 波特率: 9600(计算公式见数据手册).
MOV RCAP2L, #0B8H
MOV TH2, A
MOV TL2, A
MOV T2CON, #34H
; 设置UART1(与PC机通讯, 打印调试信息).
MOV SCON1, #70H ; 允许RI1/TI1中断.
MOV SADDR1, A
MOV SADEN1, A
; 初始化Timer4作为UART1的波特率发生器.
MOV RCAP4H, #0FFH ; 波特率: 9600.
MOV RCAP4L, #0B8H
MOV TH4, A
MOV TL4, A
MOV T4CON, #34H
; 中断寄存器配置.
; SETB EX0 ; 允许/INT0引脚的中断请求.
SETB EX1 ; 允许/INT1引脚的中断请求.
MOV IP, A ; Interrupt Priority.
MOV EIE1, A ; Extended Interrupt Enable 1.
MOV EIE2, #40H ; Extended Interrupt Enable 2.
MOV EIP1, A ; Extended Interrupt Priority 1.
MOV EIP2, A ; Extended Interrupt Priority 2.
SETB EA
RET

………………
若需更详细的代码,请Email:GaoVictor@126.com
shichaog 2011-05-05
  • 打赏
  • 举报
回复
谢谢,已清零了,见源代码~!
codesnail 2011-05-04
  • 打赏
  • 举报
回复
中断标志清零了吗
codesnail 2011-05-04
  • 打赏
  • 举报
回复
波特率有点偏高。

只能给出思路,写最简单的程序,只通讯单个字节,先用4800bps,这样做的原因是判断硬件无误,然后再追加功能。

27,509

社区成员

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

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