51单片机串口发送不了数据

sixto47 2017-11-24 09:11:42
以下是程序
#include<reg52.h>
#include<stdio.h>
#include "18b20.h"
#include "1602.h"
#include "delay.h"
#include "dht11.h"

#define KeyPort P1
sbit SPK=P2^5;
bit ReadTempFlag;//定义读时间标志
bit ReadDamFlag;
void Init_Timer0(void);//定时器初始化
unsigned char KeyScan(void);//键盘扫描
/*------------------------------------------------
串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TR1 = 1; // TR1: timer 1 打开
//EA = 1; //打开总中断
//ES = 1; //打开串口中断
TI=1;
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
int temp,tempH=20,tempL=10;
int dam,damH=60,damL=20;
float damh;
float temperature;
char displaytemp[16],num;//定义显示区域临时存储数组

LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
Init_Timer0();
UART_Init();
Lcd_User_Chr(); //写入自定义字符

LCD_Write_String(0,0,"www.jyumcu.com");
LCD_Write_String(0,1,"welcome");
while (1) //主循环
{DelayMs(20);
num=KeyScan();
switch(num)
{
case 1:if(tempH<127)tempH++;break;
case 2:if(tempH>-55)tempH--;break;
case 3:if(tempL<127)tempL++;break;
case 4:if(tempL>-55)tempL--;break;
case 5:if(damH<100) damH++;break;
case 6:if(damH>-40) damH--;break;
case 7:if(damL<100) damL++;break;
case 8:if(damL>-40) damL--;break;
default:break;
}

sprintf(displaytemp,"DH=%3d DL=%3d",damH,damL);
LCD_Write_String(0,1,displaytemp);
DelayMs(20);
sprintf(displaytemp,"H=%3d L=%3d ",tempH,tempL);//输出温度上限下限

LCD_Write_String(0,1,displaytemp);//显示第二行


damh=DHT11_ReadTempAndHumi();
if(damh>damH)
LCD_Write_String(0,0," over DAMH");
else if (damh<damL)
LCD_Write_String(0,0," under DAML");

if(ReadTempFlag==1)
{
ReadTempFlag=0;
temp=ReadTemperature();

if(temp&0x8000)
temp=0-temp;//变为负数

temperature=temp*0.0625;

temp>>=4;
if(temp>tempH)
LCD_Write_String(0,0," over tempH ");
else if(temp<tempL)
LCD_Write_String(0,0," under tempL ");

sprintf(displaytemp,"T=%3.1f D=%3.1f",temperature,damh);//打印温度值
LCD_Write_String(0,0,displaytemp);//显示第一行
LCD_Write_Char(6,0,0x01);//写入温度右上角点
LCD_Write_Char(7,0,'C'); //写入字符C

}
if(temp>tempH ||temp<tempL || damh >damH || dam <damL)
SPK=1;
}

}

/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00; //给定初值
//TL0=0x00;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
static unsigned int num;
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;

num++;
if(num==400) //
{
num=0;
ReadTempFlag=1; //读标志位置1
}
}

/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void)
{
unsigned char keyvalue;
if(KeyPort!=0xff)
{
DelayMs(10);
if(KeyPort!=0xff)
{
keyvalue=KeyPort;
while(KeyPort!=0xff);
switch(keyvalue)
{
case 0xfe:return 1;break;
case 0xfd:return 2;break;
case 0xfb:return 3;break;
case 0xf7:return 4;break;
case 0xef:return 5;break;
case 0xdf:return 6;break;
case 0xbf:return 7;break;
case 0x7f:return 8;break;
default:return 0;break;
}
}
}
return 0;
}
...全文
1805 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_39121699 2018-01-26
  • 打赏
  • 举报
回复
我感觉可能是定时器初始化的问题,具体的我忘了,你可以试一下
乘风破浪2016 2017-11-27
  • 打赏
  • 举报
回复
以下是我当初学习串口通信的功能比较全的代码,楼主可以参考下,去掉一些不用的就行了 #include<reg52.h> #include<stdio.h> // #include<inrins.h> #define unint unsigned int #define unchar unsigned char #define PCF8591_WRITE 0x90 //本机的PCF8591芯片地址为 1001 0000 即为低四位的前三位为000.不同开发板可能不同 #define PCF8591_READ 0x91 unchar ge,shi,bai,idata receive_da, flg,flg1,ad_p,flg_on,ReData,t0_num; unint D[10]; unchar AD_CHANNEL; sbit SDA=P2^1; sbit SCL=P2^0; sbit dula=P1^0; sbit LS138A=P2^2; sbit LS138B=P2^3; sbit LS138C=P2^4; float ad_vo; unchar code Disp_Tab[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x67,0x7c, 0x39,0x5e,0x79,0x71 }; init1() //串口初始化 { SCON = 0x50; //REN=1允许串行接受状态,串口工作模式1 TMOD|= 0x21; //定时器1工作方式2,定时器2 PCON|= 0x80; //电源管理寄存器用于波特率是否加倍 TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1 = 0xF3; // //baud*2 /* 波特率4800、数据位8、停止位1。效验位无 (12M) TL1 = 0xF3; TR1 = 1; ES = 1; //开串口中断 EA = 1; // 开总中断 ET0=1; //开定时器0中断 } void delay() //响应函数 { ; ; } void init() //总线初始化函数 { SDA=1; delay(); SCL=1; delay(); } void iic_start() //启动函数 { SDA=1; delay(); SCL=1; delay(); SDA=0; delay(); /*SCL=0; delay(); */ } void STOP_I2C() //停止信号 { SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); } void ACK_I2c() // 应答 { unint i; SCL=1; delay(); while((SDA=1)&&(i<255)) i++; SCL=0; delay(); } void NOACK_I2c() //非应答 { SCL=1; delay(); SDA=0; SCL=0; delay(); } void write_byte(unchar date ) { unchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY; delay(); SCL=1; delay(); } // SCL=1; 调试时的错误 SCL=0; delay(); SDA=1; delay(); SCL=1; delay(); } unchar read_byte() { unchar k,j; SCL=0; // 为下一步SDA=1作准备 delay(); SDA=1;//置“读取数据”模式 delay(); //以便数据变化 for(j=0;j<8;j++) { SCL=1;///让数据稳定才能读操作 delay(); k=(k<<1)|SDA; SCL=0;//完成一个时钟 delay(); } return k; } unchar ADC_PCF8591(unchar controlbyte) //完整的AD转换函数,注意要先写后读 { unchar c,i=0; iic_start(); write_byte(PCF8591_WRITE); ACK_I2c(); write_byte(controlbyte); //控制字 ACK_I2c(); iic_start(); write_byte(PCF8591_READ); ACK_I2c(); c=read_byte(); NOACK_I2c(); STOP_I2C(); return(c); //返回读的数据 } deplay() { unchar i,j; unchar LedOut[8]; /********以下AD-DA处理*************/ switch(AD_CHANNEL) { case 0: D[0]=ADC_PCF8591(0x41); //ADC0 模数转换1 break; case 1: D[1]=ADC_PCF8591(0x42); //ADC1 模数转换2 break; case 2: D[2]=ADC_PCF8591(0x43); //ADC2 模数转换3 break; case 3: D[3]=ADC_PCF8591(0x40); //ADC3 模数转换4 break; // case 4: DACconversion(0x90,0x40, D[4]/4); //DAC 数模转换 // break; } // D[4]=400; //数字--->>模拟输出 //D[4]=D[0]; // 把模拟输入 采样的信号 通过数模转换输出 if(++AD_CHANNEL>4) AD_CHANNEL=0; /********以下将AD的值送到LED数码管显示,本程序只使用了两个通道即D1和D2*************/ LedOut[0]=Disp_Tab[D[0]%10000/1000]; LedOut[1]=Disp_Tab[D[0]%1000/100]; LedOut[2]=Disp_Tab[D[0]%100/10]; LedOut[3]=Disp_Tab[D[0]%10]; LedOut[4]=Disp_Tab[0]; LedOut[5]=Disp_Tab[0]; LedOut[6]=Disp_Tab[0]; LedOut[7]=Disp_Tab[0]; /*D[0]才是数码转换后的数据*/ for( i=0; i<8; i++) { P0 = LedOut[i]; switch(i) //使用switch 语句控制138译码器 也可以是用查表的方式 学员可以试着自己修改 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } for (j = 0 ; j<90 ;j++) { ;} //扫描间隔时间 } P0 = 0; } void ser_int (void) interrupt 4 using 1 { RI = 0; //清除RI接受中断标志 ReData = SBUF; //在电脑上点击发送按钮即将数据发送给单片机,flag=1表示单片机接收到了上位机发送的数据 // SenData=ReData; flg1=1; if(ReData ==1) flg_on=0; else if(ReData ==2) flg_on=1; else flg_on=2; } void T0_time()interrupt 1 //定时1S使flg=1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; t0_num++; if(t0_num==20) { t0_num=0; flg=1; } } void main() { init1();//串口初始化 init(); while(1) { if(flg1==1)//串口中断信号 { flg1=0; ES=0; TI=1; switch(flg_on) { case 2:puts("Turn on ad!\n"); TR0=1;//启动定时器T0便于后面每秒发送一次数据 //TF0=1; flg=1; break; case 1:printf("Turn off ad!\n"); TR0=0; break; case 0:puts("Error\n"); TR0=0; break; } while(TI==0); TI=0; ES=1; } if(flg==1) { flg=0; ad_p=D[0];//此处是将ad转换后的数据赋给ad_p ad_vo=(float)ad_p*5.0/255; ES=0; TI=1; printf("The volage is %fV\n",ad_vo); while(TI==0); TI=0; ES=1; //TF0=0; } deplay(); } } /*本程序已经成功显示了实际电压值,以及转换后的3位十进制数,用到了AD转换,数码显示等知识点*/
sixto47 2017-11-25
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
那应该怎么改? 没看到你串口发送字符的代码 /* character to output */ char putchar (char c) { SBUF = c; while(!TI); TI = 0; return c; } //主循环 void main() { init_uart(); while(1) { printf("test\r\n"); } }
zgl7903 2017-11-25
  • 打赏
  • 举报
回复
没看到你串口发送字符的代码 /* character to output */ char putchar (char c) { SBUF = c; while(!TI); TI = 0; return c; } //主循环 void main() { init_uart(); while(1) { printf("test\r\n"); } }

27,370

社区成员

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

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