51单片机串口控制继电器的C源程序
详解一个电脑串口控制单片机驱动继电器的例子(全部源代码)
开源详解(看完如觉得不错,请顶一下哦!)声明:软件版权归作者完全所有。
未经作者授权,请勿在任何第三方杂志、报刊、网站转载或发表,本程序仅供学习研究用,您可以自由拷贝、散发本程序,但不能用于商业目的。
很多网上认识的朋友,提到这个话题,在此用此例给热爱单片机的朋友!---一个简单的串口控制继电器的例子(全部源代码)-- 马工2006-5-8 20:00下面的文章详细的说明了如何在PC端编制控制程序,并且通过串口输出数据来控制单片机硬件,单片机外围连接了若干继电器,达到控制继电器开关的作用。
要说的是,有很多的方法可以实现上述的功能,下面的方法只是其中的一种,并且出于便于大家学习阅读的目的,很多代码并没有进行优化,而是将其展开编写,在你理解后,你完全可以在此基础上修改、优化代码,使之更优化和精简,并符合你的其他要求。
如果你读完这篇文章,觉得给你带来了帮助,我非常高兴。
如果你无法理解,你应该再看一下其他更基础的书籍、文章。
我想应该分成二个部分来讲(单片机部分、PC程序部分),并且希望能写得较为详细,把基础的讲述清楚。
1、单片机部分电路图:此主题相关图片如下:单片机源代码(asm格式):;--------------------------------------------------;--------------------------------------------------;设置串行口波特率9600;串行口设置MODE1,SM1=0,REN=1,SMOD=1;晶振11.0592,定时设置为0FDH;常用端口设置参数;FD 9600;FA 4800;F4 2400;E8 1200;--------------------------------------------------;*********************************************************** ORG 00HJMP STARTORG 23HJMP UARTORG 30HSTART: MOV SP,#70HMOV SCON,#50HMOV TMOD,#00100001B ;TIM1在模式2 TIM0在模式1MOV TH1,#0F4H ;设置定时时间SETB TR1 ;启动定时器1SETB ES ;允许串口中断SETB EA ;允许总中断MOV P0,#0 ;P0、P2输出低电平MOV P2,#0JMP $ ;等待状态;*****************************************;串行口中断;*****************************************UART: PUSH ACCPUSH PSWCLR ES ;关闭串行口中断MOV TH0,#HIGH(65536-65536)MOV TL0,#LOW(65536-65536)SETB TR0 ;开定时器0MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位MOV R0,#30HREC:jbc tf0,FS ;接收时间是否超时?是则执行FSJNB RI,REC ;接收数据CLR RIMOV A,SBUFMOV @R0,AINC R0JMP RECFS: CLR TR0 ;关定时器0;********************************CALL FUN ;解码并控制继电器SETB ES ;开串行口中断POP PSWPOP ACCRETI ;中断子程序返回;**************************************** ;解码并控制继电器;下面的程序可以更简洁,但为了方便,展开来编制;**************************************** FUN: MOV A,#0AH ;判断第1字节即同步位CJNE A,30H,ERRMOV A,#0DH ;判断第4字节即结束位CJNE A,33H,ERR;****************************************;第2字节即数据位1,代表继电器J1-8;第3字节即数据位2,代表继电器J9-16;**************************************** MOV A,31HMOV P0,AMOV A,32HMOV P2,ARET;**************************************; 数据错误处理;************************************** ERR:MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位RETEND ;程序结束;--------------------------------------------------;--------------------------------------------------单片机源代码(asm格式)+电路图下载:点击浏览该文件电路图说明:这个电路非常典型,串行口(也称RS232)接口集成电路MAX232与单片机AT89S51引脚P3.0(RXD)\P3.1(TXD)连接,构成与主机的通讯接口电路。
基于51单片机的CAN通讯协议C语言程序
// 入口函数 无
// 出口函数 无
// 全局变量 SJA_workmode
// 操作寄存器 控制寄存器(地址00)
// 函数功能 设置SJA工作在复位模式
#define SJA_RIE 0 //接收中断
//-----------------------定义地址指针,指向基址--------------------------------------------------------
bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式
//SJA_workmode=0工作在复位模式
#define base_Adr 0x00
//-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x00 //该值需要用户根据实际需要的波特率进行计算
//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
}BASICCAN_FRAME,receive_BUF,send_BUF;
//BASICCAN_BUFstruct send_BUF;
//------------------------------------------------------------------------------------------------------
51单片机经典C程序(12864)
/*************************************** 控制器:KS0108* MCU:AT89C5* ,晶体频率:12MHz* 取模方式:纵向字节倒序* CS1和CS2为低电平有效**************************************/#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define LCD_PORT P0#define Left 1#define Right 2sbit LCD_Busy=P0^7;sbit LCD_EN = P1^2;sbit LCD_RS = P1^0;sbit LCD_RW = P1^1;sbit LCD_RST= P1^7;sbit LCD_CS2= P3^6;sbit LCD_CS1= P3^5;uchar DisBuf[32],Page_Num,Clm_Num;code char Table0[]={/*-- 文字: A --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27 ,0x38,0x20,/*-- 文字: B --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11 ,0x0E,0x00,/*-- 文字: C --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10 ,0x08,0x00,/*-- 文字: D --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10 ,0x0F,0x00,/*-- 文字: E --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20 ,0x18,0x00,/*-- 文字: F --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00 ,0x00,0x00,/*-- 文字: G --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E ,0x02,0x00,};code unsigned char Table3[]={/*-- 文字: 天 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x40,0x42,0x42,0x42,0x42,0x42,0xFE,0x42,0x42,0x42,0x42,0x42,0x42 ,0x40,0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x06,0x01,0x02,0x04,0x08,0x10,0x30,0x60 ,0x20,0x00,/*-- 文字: 仙 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x80,0x60,0xF8,0x07,0x02,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00 ,0xE0,0x00,0x01,0x00,0x00,0x7F,0x00,0x20,0x7F,0x20,0x20,0x20,0x3F,0x20,0x20,0x20 ,0x7F,0x00,/*-- 文字: 妹 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x88,0x7F,0x0A,0x08,0xF8,0x80,0x88,0x88,0x88,0xFF,0x88,0x88,0x88 ,0x80,0x00,0x40,0x21,0x12,0x0C,0x3A,0x11,0x40,0x30,0x0C,0x03,0xFF,0x06,0x08,0x30 ,0x10,0x00,/*-- 文字: 妹 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x88,0x7F,0x0A,0x08,0xF8,0x80,0x88,0x88,0x88,0xFF,0x88,0x88,0x88 ,0x80,0x00,0x40,0x21,0x12,0x0C,0x3A,0x11,0x40,0x30,0x0C,0x03,0xFF,0x06,0x08,0x30 ,0x10,0x00};code unsigned char Table4[]={/*-- 文字: 我 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x20,0x22,0x22,0xFE,0x21,0x21,0x20,0x20,0xFF,0x20,0x22,0xAC,0x20 ,0x20,0x00,0x04,0x04,0x42,0x82,0x7F,0x01,0x01,0x10,0x10,0x08,0x07,0x1A,0x21,0x40 ,0xF0,0x00,/*-- 文字: 好 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x10,0xF0,0x1F,0x10,0xF0,0x80,0x82,0x82,0x82,0xF2,0x8A,0x86,0x82 ,0x80,0x00,0x80,0x43,0x22,0x14,0x0C,0x73,0x20,0x00,0x40,0x80,0x7F,0x00,0x00,0x00 ,0x00,0x00,/*-- 文字: 想 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0xC8,0x38,0xFF,0x18,0x68,0x08,0x00,0xFE,0x2A,0x2A,0x2A,0x2A,0xFE ,0x00,0x00,0x01,0x40,0x70,0x01,0x38,0x40,0x40,0x44,0x59,0x41,0x41,0x61,0x01,0x09 ,0x30,0x00,/*-- 文字: 你 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x80,0x40,0xF0,0x2C,0x43,0x20,0x98,0x0F,0x0A,0xE8,0x08,0x88,0x28,0x1C ,0x08,0x00,0x00,0x00,0x7F,0x00,0x10,0x0C,0x03,0x21,0x40,0x3F,0x00,0x00,0x03,0x1C ,0x08,0x00};code unsigned char Table5[]={/*-- 调入了一幅图像:C:\Documents and Settings\sammy\桌面\小新.bmp --*//*-- 宽度x高度=64x64 --*/0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0 ,0xF8,0x7C,0x3C,0x1E,0x1E,0x8F,0xCF,0xCF,0xCF,0xDF,0x9F,0x9F,0x1F,0x1F,0x3F,0x3E ,0x3E,0x3E,0x7C,0x7C,0x7C,0xF8,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x10,0x08,0x08,0x1E,0x3F,0x7F,0x03 ,0x00,0x00,0x00,0x06,0x07,0x07,0x03,0x03,0x03,0x0F,0x3F,0x3F,0x7E,0x78,0x78,0x30 ,0x00,0x00,0x00,0x00,0x60,0xE0,0xF0,0x78,0x39,0x39,0x73,0xFE,0x60,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x03,0x04,0x08,0x11,0x08,0x04,0x83,0x80,0x0C,0x92,0xA2,0x44 ,0x22,0x12,0x00,0x00,0x00,0x00,0x00,0x0F,0x30,0x40,0x80,0x80,0x80,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x02,0x02,0x04,0x04,0x04,0x08,0x08,0x08,0x08,0x10,0x10,0x00 ,0x00,0x00,0x00,0x40,0x40,0x80,0x80,0x80,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00 ,0x00,0x60,0x90,0x10,0x20,0x10,0x90,0x60,0x00,0x03,0x04,0x08,0x11,0x08,0x04,0x03 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10 ,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x06,0xF8,0x00,0x00 ,0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F ,0x7F,0xFF,0xF3,0xF3,0xFE,0xFC,0xFC,0xF8,0xF8,0xF0,0xF0,0xF0,0xE0,0xE0,0xE0,0xE0 ,0xE0,0xE0,0xE4,0xE0,0xE0,0xE0,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x01,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xD8,0xD8,0xFC ,0xFC,0xFC,0xFD,0xFD,0xFF,0xF7,0xF7,0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xF3,0xF7,0xF7 ,0xFF,0xFF,0xFF,0xFD,0xFD,0xFC,0xDC,0xD8,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0 ,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0 ,0xC0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF};code uchar Table8[]={/*-- 文字: 相 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x10,0xD0,0xFF,0x30,0x50,0x90,0x00,0xFE,0x22,0x22,0x22,0x22,0xFE ,0x00,0x00,0x04,0x03,0x00,0xFF,0x00,0x00,0x01,0x00,0xFF,0x42,0x42,0x42,0x42,0xFF ,0x00,0x00,/*-- 文字: 约 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x40,0x60,0x58,0xC7,0x60,0x18,0x40,0x20,0x58,0x8F,0x08,0x08,0x08,0xF8 ,0x00,0x00,0x10,0x32,0x13,0x12,0x0A,0x0A,0x08,0x00,0x00,0x00,0x43,0x80,0x40,0x3F ,0x00,0x00,/*-- 文字: 丛 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0xFE,0x80,0x00,0x00,0x00 ,0x00,0x00,0x20,0x30,0x2C,0x23,0x20,0x21,0x36,0x2C,0x23,0x20,0x20,0x23,0x26,0x3C ,0x28,0x00,/*-- 文字: 林 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x10,0x90,0xFF,0x90,0x10,0x00,0x10,0x10,0xD0,0xFF,0x90,0x10,0x10 ,0x10,0x00,0x08,0x06,0x01,0xFF,0x00,0x13,0x08,0x04,0x03,0x00,0xFF,0x01,0x06,0x18 ,0x08,0x00};code uchar Table9[]={/*-- 文字: 浪 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x30,0x01,0xC6,0x30,0x00,0xFC,0x94,0x95,0x96,0x94,0x94,0xFC,0x00 ,0x00,0x00,0x04,0x04,0xFE,0x01,0x00,0x00,0xFF,0x40,0x21,0x06,0x08,0x34,0x62,0xC2 ,0x40,0x00,/*-- 文字: 漫 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x20,0x81,0x66,0x00,0xC0,0x5F,0xD5,0x55,0x55,0xD5,0x55,0x5F,0xC0 ,0x00,0x00,0x04,0xFC,0x03,0x00,0x00,0x81,0x85,0x4D,0x55,0x25,0x35,0x4D,0xC5,0x41 ,0x00,0x00,/*-- 文字: 野 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x7E,0x4A,0xFE,0x4A,0x4A,0x7E,0x00,0x42,0x52,0xD2,0x6A,0x46,0xC2 ,0x40,0x00,0x22,0x22,0x22,0x1F,0x12,0x12,0x12,0x00,0x40,0x80,0x7F,0x00,0x00,0x00 ,0x00,0x00,/*-- 文字: 岭 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0xF0,0x00,0xFF,0x00,0xF0,0x40,0x20,0x10,0x2C,0x43,0x04,0x08,0x70 ,0x20,0x00,0x08,0x1F,0x08,0x07,0x04,0x07,0x01,0x05,0x09,0x11,0x29,0x65,0x03,0x01 ,0x00,0x00};void Delay_us(unsigned int DelayTime){while(DelayTime) DelayTime--;}void Delay_x10ms(unsigned char DelayTime) //***************10ms延时**********//{unsigned char i,j,k;for(i=0;i<DelayTime;i++)for(j=0;j<10;j++)for(k=0;k<120;k++) {;}}/*----------------------------------------------------------------------------下面这个函数用于液晶模块的忙信号检测。
基于51的温度控制系统设计C语言源程序
/*********************************************************//*程序名称:温度监控系统*//*程序功能:利用89C52单片机和DS18B20温度传感器实现环境*//* 温度的实时测量和高、低温报警*//*程序版本:v1.0 *//*作者:*//*编写时间:*//*********************************************************/#include 〈reg52。
h>#include 〈intrins.h〉//含_nop_()延时函数//定义数据类型#define uchar unsigned char#define uint unsigned int//定义端口#define LED P0 //段码输出口sbit DQ = P3^2;//传感器数据口sbit SMG_q = P1^0;//定义数码管阳级控制脚(千位)sbit SMG_b = P1^1;//定义数码管阳级控制脚(百位)sbit SMG_s = P1^2; //定义数码管阳级控制脚(十位)sbit SMG_g = P1^3;//定义数码管阳级控制脚(个位)sbit buzzer = P1^5;//蜂鸣器sbit led_low = P2^6; //低温指示灯sbit led_high = P2^7;//高温指示灯sbit led_ok = P2^5; //温度正常指示灯sbit led_work = P2^4;//工作指示灯sbit set = P3^7;//设置按键sbit add = P3^4;//加一按键sbit dec = P3^5;//减一按键//定义变量和常量int count = 0;//按键次数寄存器int h;//主函数用循环计数器uint temp; //温度值uchar r; //温度值整数形式uchar high = 35,low = 20; //上下限初值//共阳LED段码表"0" ”1”"2”"3" "4””5" "6””7”"8" ”9””不亮" ”—"uchar code LED_code[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar code LED_code1[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//小数部分转换码表uchar data temp_data[2]= {0x00,0x00};//存储从传感器读出的温度值uchar data dp[5]= {0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算//子函数声明void ds_reset();//DS18B20初始化函数void ds_write(uchar ds_wrdata);//DS18B20写数据函数uchar ds_read(); //DS18B20读数据函数read_temp(); //读取温度函数void change_temp(uint tem);//温度数据处理void xianshi(int horl);//温度显示转换void display(); //数码管显示函数void keyscan(); //按键查询函数void warn_led();//超限报警void delay(uint t);//延时函数,单次25us/********************主函数*********************/void main(){LED=0x00; //初始化显示端口led1=0;led2=0;led3=0;led4=0;for(h=0;h<4;h++){dp[h]=8;}while(1) //循环执行显示和温度读取{uchar i;for(i=0;i〈200;i++){warn_led(); //指示灯控制display(); //显示keyscan(); //按键扫描}change_temp(read_temp());//温度数据读取和处理}}/***********************************************//*函数名称:ds_reset()*//*函数功能:DS18B20初始化*//*入口参数:无*//*输出参数:无*//*调用函数:delay();_nop_(); *//*全局变量:无*//*局部变量:presence *//***********************************************/void ds_reset(void){char presence=1;while(presence){while(presence){DQ=1;//传感器数据段先置高电平_nop_();_nop_();//适当延时DQ=0; //传感器数据段从高电平拉到低电平delay(50); //延时DQ=1; //再置高电平delay(6);//延时presence=DQ; //初始化成功,继续下一步}delay(45); //延时presence=~DQ;}DQ=1; //拉高电平led_work=0; //开工作指示灯}/***********************************************//*函数名称:ds_write() *//*函数功能:向DS18B20写数据*//*入口参数:ds_wrdata *//*输出参数:无*//*调用函数:delay();_nop_(); *//*全局变量:无*//*局部变量:ds_wrdata *//***********************************************/ void ds_write(uchar ds_wrdata){uchar i;for(i=8;i〉0;i——){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=ds_wrdata&0x01; //最低位移出delay(6);ds_wrdata=ds_wrdata/2;//右移1位}DQ=1;delay(1);}/***********************************************/ /*函数名称:ds_read()*//*函数功能:从DS18B20读数据*//*入口参数:无*//*输出参数:value *//*调用函数:delay();_nop_();*//*全局变量:*//*局部变量:i;value; *//***********************************************/uchar ds_read(void){uchar i;uchar value=0;for(i=8;i>0;i-—){DQ=1;_nop_();_nop_();value〉>=1;DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_();if(DQ)value|=0x80;delay(6);}DQ=1;return(value);}/***********************************************/ /*函数名称:read_temp()*//*函数功能:读温度数据数据*//*入口参数:无*//*输出参数:yemp *//*调用函数:ds_reset();ds_write();ds_read();*//* delay(); *//*全局变量:temp *//*局部变量:temp_data[];*//***********************************************/ read_temp(){ds_reset();//传感器初始化delay(200);ds_write(0xcc);//发跳过读取序列号命令ds_write(0x44); //发温度转换命令ds_reset();delay(1);ds_write(0xcc);ds_write(0xbe);//读18B20中存储器temp_data[0]=ds_read();//读温度值的低字节命令temp_data[1]=ds_read(); //读温度值的高字节temp=temp_data[1];temp<〈=8;temp=temp|temp_data[0]; //两字节合成一个整型变量return temp;//返回温度值}/***********************************************/ /*函数名称:chang_temp() *//*函数功能:将温度传感器中独到的数据进行转换*//*入口参数:tem *//*输出参数:dp[]*//*调用函数:无*//*全局变量:dp[];ditab[];r; *//*局部变量:tem *//***********************************************/void change_temp(uint tem){uchar n=0;if(tem>6348) // 温度值正负判断{tem=65536—tem; // 负温度求补码n=1; //标志位置1}dp[4]=tem&0x0f; // 取小数部分的值dp[0]=ditab[dp[4]];// 存入小数部分显示值dp[4]=tem〉〉4;// 取中间八位,即整数部分的值dp[3]=dp[4]/100; // 取百位数据dp[1]=dp[4]%100;// 取后两位数据dp[2]=dp[1]/10;// 取十位数据dp[1]=dp[1]%10;// 个位r=dp[1]+dp[2]*10+dp[3]*100;//实际温度值(十进制)if(!dp[3])//符号位显示判断{dp[3]=0x0a; //最高位为0时不显示if(!dp[2]){dp[2]=0x0a;//次高位为0时不显示}}if(n){dp[3]=0x0b;//负温度时最高位显示"—”}}/***********************************************//*函数名称:xianshi() *//*函数功能:温度数据转换成显示所需LED段码*//*入口参数:horl *//*输出参数:dp[] *//*调用函数:无*//*全局变量:dp[]; *//*局部变量:n; *//***********************************************/ void xianshi(int horl){int n=0;if(horl〉128) //负数补码转换{horl=256—horl;n=1;}dp[3]=horl/100;dp[3]=dp[3]&0x0f; //百位dp[2]=horl%100/10; //十位dp[1]=horl%10;//个位dp[0]=0; //小数位if(!dp[3])//高位为零不显示{dp[3]=0x0a;if(!dp[2]){dp[2]=0x0a;}}if(n) //负数最高位显示“—"{dp[3]=0x0b;}}/***********************************************/ /*函数名称:display()*//*函数功能:数码管显示*//*入口参数:无*//*输出参数:无*//*调用函数:delay() *//*全局变量:dp[];LED_code[];LED_code1[];*//*led1;led2;led3;led4; *//*局部变量:j;*//***********************************************/ void display(){int j;for(j=0;j<4;j++) //4位LED扫描控制{switch(j){case 0:LED=LED_code[dp[0]];led4=1;delay(450);led4=0;break;//小数位case 1:LED=LED_code1[dp[1]];led3=1;delay(450);led3=0;break;//个位case 2:LED=LED_code[dp[2]];led2=1;delay(450);led2=0;break;//十位case 3:LED=LED_code[dp[3]];led1=1;delay(450);led1=0;break; //百位}}}/***********************************************/ /*函数名称:keyscan() *//*函数功能:按键查询*//*入口参数:无*//*输出参数:无*//*调用函数:delay();display();xianshi();*//*全局变量:count;high;low; *//*局部变量:无*//***********************************************/ void keyscan(){if(set==0) //set键按下{while(1){delay(500);//延时去抖动if(set==0)//重新判断set键是否按下{count++;while(!set)//按键弹起继续显示前面内容display();}if(count==1)//set按下一次执行此段{xianshi(high);//转换上限温度为段码并显示display();if(add==0) //add键是否按下{while(!add)//弹起时上限温度加一并显示display();high+=1;}if(dec==0)//dec键是否按下{while(!dec) //弹起时上限温度减一并显示display();high—=1;}}if(count==2)//set键按下两次执行此段{xianshi(low);//转换下限温度为段码并显示display();if(add==0) //add键是否按下{while(!add)//弹起时下限温度加一并显示display();low+=1;}//dec键是否按下if(dec==0){while(!dec)//弹起时下限温度减一并显示display();low—=1;}}if(count>=3)//set键按下三次回到温度显示状态{count=0;break;}}}}/***********************************************//*函数名称:warn_led() *//*函数功能:工作情况指示灯控制*//*入口参数:无*//*输出参数:无*//*调用函数:无*//*全局变量:high;low;r; *//*局部变量:无*//***********************************************/ void warn_led(){if(r〉high)//温度高于上限温度{led_low=1;//“低温”指示灯灭led_high=0;//“高温"指示灯亮led_ok =1;//“正常"指示灯灭buzzer = 0; //蜂鸣器发声}else if(r〈low)//温度低于下限温度{led_low=0;//“低温"指示灯亮led_high=1;//“高温”指示灯灭led_ok =1; //“正常”指示灯灭buzzer = 0; //蜂鸣器发声}else //温度正常{led_low=1; //“低温”指示灯灭led_high=1;//“高温”指示灯灭led_ok =0; //“正常"指示灯亮buzzer = 1; //蜂鸣器不发声}}/***********************************************/ /*函数名称:delay() *//*函数功能:延时函数,单次25us左右延时*//*入口参数:t; *//*输出参数:无*//*调用函数:无*//*全局变量:无*//*局部变量:t;*//***********************************************/void delay(uint t){for (;t〉0;t—-);}/*******************程序结束********************/。
51单片机串口控制继电器
51单片机串口控制继电器
实验室有个项目,用到报警功能。
比如当温度或应力过高或者过低的时候启动报警器,通过给串口发送一个命令来控制继电器。
不巧去年被我正负极接反烧了,最近开始搞单片机,哥苦心经营,利用实验室单片机学习板给搞定了,程序如下:
#include;
#define uchar unsigned char
sbit JDQ=P3^7; //继电器接P3.7
sbit FMQ=P3^6;
sbit LED=P0^0;
sbit LEDra=P0^1;
sbit LEDar=P0^2;
uchar dat[4];
int i=0;
void Delay(unsigned int ii) //1mS
{
unsigned int jj;
for(;ii>;0;ii--)
for(jj=0;jj;=4)i=0;else;
}
EA=1;
}
main() //串口方式1发送时的定时信号,也就是移位脉冲,由定时器1产生。
不是定时器0。
{
init_serialcom();
Delay(10);
while(1);
}
第一次独立写的,程序粗糙了点,但是完美运行。
发送:E5A1 104E,继电器闭合
E5A1 114D,继电器断开
这里控制用到了四个字节,所以在中断程序里面我定义了一个数组,最后判断这四个字节是否都正确。
如果一个字节的话更简单。
下一步要用无线控制,等哥哥好消息吧。
C51 程序(数码管、继电器等控制程式)解析
以下程式,为T8试烧台的控制程式:器件有六位数码管显示、报警器、和控制交流接触器的12V继电器。
#include <reg52.h>#define uint unsigned int#define uchar unsigned charsbit set=P3^0; //设置时间,按一下相应的位闪烁;sbit jia=P3^3; //设置位按一下加1;sbit jian=P3^6; //设置位按一下减1;sbit go=P3^1; //功能启动按钮;sbit relay1=P2^7; //控制功率;sbit relay2=P2^6; //控制警报;sbit relay3=P2^5; //控制功率;sbit relay4=P2^4; //控制警报;uchar code table[]={ //显示编码0,1,2,3,4,5,6,7,8,9,-,H,E,L,U,R~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f,~0x40,~0x76,~0x79,~0x38,~0x3e,~0x77,~0x49,~0x79,~0x38,~0x3f};uchar fen,miao,t0,t1,t2,set_flag,set_wei_flag,jia_flag,jian_flag,go_flag;uchar shi_qianwei,shi_baiwei,shi_shiwei,shi_gewei,fen_shiwei,fen_gewei,miao_shiwei,miao_gewei;uchar set_fen,set_miao,shan,shan_over;char set_shi_q,set_shi_b,set_shi_s,set_shi_g,set_fen_s,set_fen_g,set_miao_s,set_miao_g,set_wei;int shi,set_shi,jingbao;void delay(uint z) //延时函数1ms ;{uint t1,y;for(t1=z;t1>0;t1--)for(y=100;y>0;y--);}void MCUinit() //初始化MCU;{P0=0;P1=0;P2=0;P3=0;set=1;jia=1;jian=1;go =1;set_shi_q=0;set_shi_b=0;set_shi_s=0;set_shi_g=0;set_fen_s=0;set_fen_g=0;set_miao_s=0;set_miao_g=0;set_wei=7;set_flag=0;jia_flag=0;jian_flag=0;go_flag=0;shi=0;fen=0;miao=0;t0=0;t1=0;shan=0;jingbao=0;TMOD=0x11; //使能定时器并加入初值TH0=(65536-50000)/256;TL0=(65536-50000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;EA=1;ET0=1;ET1=1;TR1=1;}void setscanf() // 设置函数{while(set_flag==1){if(set_shi<=99){if(set_wei_flag==1) //设置位自左往右循环;{set_wei_flag=0;set_wei--;if(set_wei<1)set_wei=6;}switch(set_wei){case 1:{if(jia_flag==1){jia_flag=0;set_miao_g++;if(set_miao_g>9)set_miao_g=0;}if(jian_flag==1){jian_flag=0;set_miao_g--;if(set_miao_g<0)set_miao_g=9;}//时十位;=============================P0=table[set_shi_s];P1=0x20;delay(1);P0=0xff;//时个位;=============================P0=table[set_shi_g];P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[set_fen_s];P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_fen_g];P1=0x04;delay(1);P0=0xff;P0=table[set_miao_s];P1=0x02;delay(1);P0=0xff;//秒个位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_miao_g]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x01;delay(1);P0=0xff;break;}case 2:{if(jia_flag==1){jia_flag=0;set_miao_s++;if(set_miao_s>5)set_miao_s=0;}if(jian_flag==1){jian_flag=0;set_miao_s--;if(set_miao_s<0)set_miao_s=5;}//时十位;=============================P0=table[set_shi_s];P1=0x20;delay(1);P0=0xff;P0=table[set_shi_g];P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[set_fen_s];P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_fen_g];P1=0x04;delay(1);P0=0xff;//秒十位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_miao_s]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[set_miao_g];P1=0x01;delay(1);P0=0xff;break;}case 3:{if(jia_flag==1){jia_flag=0;set_fen_g++;if(set_fen_g>9)set_fen_g=0;}if(jian_flag==1){jian_flag=0;set_fen_g--;if(set_fen_g<0)set_fen_g=9;}//时十位;============================= P0=table[set_shi_s];P1=0x20;delay(1);P0=0xff;//时个位;============================= P0=table[set_shi_g];P1=0x10;delay(1);P0=0xff;//分十位;============================= P0=table[set_fen_s];P1=0x08;delay(1);P0=0xff;//分个位;============================= if(shan<20) //数码管闪烁占空比的控制1:1 {P0=table[set_fen_g]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x04;delay(1);P0=0xff;//秒十位;============================= P0=table[set_miao_s];P1=0x02;delay(1);P0=0xff;//秒个位;============================= P0=table[set_miao_g];P1=0x01;delay(1);P0=0xff;break;}case 4:{if(jia_flag==1){jia_flag=0;set_fen_s++;if(set_fen_s>5)set_fen_s=0;}if(jian_flag==1){jian_flag=0;set_fen_s--;if(set_fen_s<0)set_fen_s=5;}//时十位;=============================P0=table[set_shi_s];P1=0x20;delay(1);P0=0xff;//时个位;=============================P0=table[set_shi_g];P1=0x10;delay(1);P0=0xff;//分十位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_fen_s]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_fen_g];P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[set_miao_s];P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[set_miao_g];P1=0x01;delay(1);P0=0xff;break;}case 5:{if(jia_flag==1){jia_flag=0;set_shi_g++;if(set_shi_g>9)set_shi_g=0;}if(jian_flag==1){jian_flag=0;set_shi_g--;if(set_shi_g<0)set_shi_g=9;}//时十位;=============================P0=table[set_shi_s];P1=0x20;delay(1);P0=0xff;//时个位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_shi_g]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[set_fen_s];P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_fen_g];P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[set_miao_s];P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[set_miao_g];P1=0x01;delay(1);P0=0xff;break;}case 6:{if(jia_flag==1){jia_flag=0;set_shi_s++;if(set_shi_s>9){set_shi_b++;set_shi_s=0;}}if(jian_flag==1){jian_flag=0;set_shi_s--;if(set_shi_s<0)set_shi_s=9;}//时十位;============================= if(shan<20) //数码管闪烁占空比的控制1:1 {P0=table[set_shi_s]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x20;delay(1);P0=0xff;//时个位;============================= P0=table[set_shi_g];P1=0x10;delay(1);P0=0xff;//分十位;============================= P0=table[set_fen_s];P1=0x08;delay(1);P0=0xff;//分个位;============================= P0=table[set_fen_g];P1=0x04;delay(1);P0=0xff;//秒十位;============================= P0=table[set_miao_s];P1=0x02;delay(1);P0=0xff;//秒个位;============================= P0=table[set_miao_g];P1=0x01;delay(1);P0=0xff;break;}}}else //画面‘三9999三’============ if(set_shi>99){if(set_wei>5)set_wei=4;if(set_wei_flag==1){set_wei_flag=0;set_wei--;if(set_wei<2)set_wei=5;}switch(set_wei){case 2:{if(jia_flag==1){jia_flag=0;set_shi_g++;if(set_shi_g>9)set_shi_g=0;}if(jian_flag==1){jian_flag=0;set_shi_g--;if(set_shi_g<0)set_shi_g=5;}//‘三’位;=============================P0=table[16];P1=0x20;delay(1);P0=0xff;//时千位;=============================P0=table[set_shi_q];P1=0x10;delay(1);P0=0xff;//时百位;=============================P0=table[set_shi_b];P1=0x08;delay(1);P0=0xff;//时分位;=============================P0=table[set_shi_s];P1=0x04;delay(1);P0=0xff;//时个位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_shi_g]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x02;delay(1);P0=0xff;//‘三’个位;=============================P0=table[16];P1=0x01;delay(1);P0=0xff;break;}case 3:{if(jia_flag==1){jia_flag=0;set_shi_s++;if(set_shi_s>9)set_shi_s=0;}if(jian_flag==1){jian_flag=0;set_shi_s--;if(set_shi_s<0)set_shi_s=9;}//时千位;============================= P0=table[16];P1=0x20;delay(1);P0=0xff;//时百位;============================= P0=table[set_shi_q];P1=0x10;delay(1);P0=0xff;//时分位;============================= P0=table[set_shi_b];P1=0x08;delay(1);P0=0xff;//时个位;============================= if(shan<20) //数码管闪烁占空比的控制1:1 {P0=table[set_shi_s]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x04;delay(1);P0=0xff;//秒十位;============================= P0=table[set_shi_g];P1=0x02;delay(1);P0=0xff;//秒个位;============================= P0=table[16];P1=0x01;delay(1);P0=0xff;break;}case 4:{if(jia_flag==1){jia_flag=0;set_shi_b++;if(set_shi_b>9)set_shi_b=0;}if(jian_flag==1){jian_flag=0;set_shi_b--;if(set_shi_b<0)set_shi_b=9;}//时十位;=============================P0=table[16];P1=0x20;delay(1);P0=0xff;//时个位;=============================P0=table[set_shi_q];P1=0x10;delay(1);P0=0xff;//分十位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_shi_b]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_shi_s];P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[set_shi_g];P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[16];P1=0x01;delay(1);P0=0xff;break;}case 5:{if(jia_flag==1){jia_flag=0;set_shi_q++;if(set_shi_q>9)set_shi_q=0;}if(jian_flag==1){jian_flag=0;set_shi_q--;if(set_shi_q<0)set_shi_q=9;}//时十位;=============================P0=table[16];P1=0x20;delay(1);P0=0xff;//时个位;=============================if(shan<20) //数码管闪烁占空比的控制1:1{P0=table[set_shi_q]&0x7f;}elseif(shan>=20){P0=0xff;}P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[set_shi_b];P1=0x08;delay(1);P0=0xff;;//分个位;=============================P0=table[set_shi_s];P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[set_shi_g];P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[16];P1=0x01;delay(1);P0=0xff;break;}}}set_shi=set_shi_q*1000+set_shi_b*100+set_shi_s*10+set_shi_g; set_fen=set_fen_s*10+set_fen_g;set_miao=set_miao_s*10+set_miao_g;if(go==0){delay(10);if(go==0)go_flag=1;set_flag=0;}continue;}}void setdisplay(uchar set_aa,uchar set_ab,uchar set_ba,uchar set_bb,uchar set_ca,uchar set_cb) {//时十位;=============================if(shi<=99){P0=table[set_aa];P1=0x20;delay(1);P0=0xff;}else{P0=table[set_aa];if(shan<=20){P1=0x20;}else{P0=0xff;}delay(1);P0=1;}//时个位;=============================P0=table[set_ab];P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[set_ba];P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[set_bb];P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[set_ca];P1=0x02;delay(1);P0=0xff;//秒个位;=============================if(shi<=99){P0=table[set_cb];P1=0x01;delay(1);P0=0xff;}else{P0=table[set_cb];if(shan<=20){P1=0x01;}else{P0=0xff;}delay(1);P0=0xff;}}//==================================================================== void display(uchar aa,uchar ab,uchar ba,uchar bb,uchar ca,uchar cb){//时十位;=============================P0=table[aa];P1=0x20;delay(1);P0=0xff;//时个位;=============================P0=table[ab]&0x7f;P1=0x10;delay(1);P0=0xff;//分十位;=============================P0=table[ba];P1=0x08;delay(1);P0=0xff;//分个位;=============================P0=table[bb]&0x7f;P1=0x04;delay(1);P0=0xff;//秒十位;=============================P0=table[ca];P1=0x02;delay(1);P0=0xff;//秒个位;=============================P0=table[cb];P1=0x01;delay(1);P0=0xff;}void initiate(){while(go_flag==1) //启动并开始计时{TR0=1;relay1=1;relay3=1;if(shi<=99) //小时数大于99,显示‘三9999三’方式{display(shi_shiwei,shi_gewei,fen_shiwei,fen_gewei,miao_shiwei,miao_gewei);}else{setdisplay(16,shi_qianwei,shi_baiwei,shi_shiwei,shi_gewei,16);}if(shi>=set_shi) //判断时间是否到设置时间{if(fen>=set_fen){if(miao>=set_miao){jingbao=0;while(1) //时间到了则停止计时,数码显示1s闪烁一次{TR0=0;relay1=0;relay3=0;if(jingbao<=20) //警报响二十秒钟,停3分钟。
51单片机串口控制继电器的C源程序
51单片机串口控制继电器的C 源程序————————————————————————————————作者:————————————————————————————————日期:51单片机串口控制继电器的C源程序2009—09-29 23:13计算机通过软件来控制单片机继电器。
操作:计算机使用串口调试助手,当然,可以自己编写控制软件(上位机软件).单片机P1.1口连上继电器C源程序为:#include 〈reg52。
h〉sbit RELAY = P1^1; //定义继电器:接P1^1void delay(unsigned int cnt){while(--cnt);}main(){TMOD=0x20; //TH1=0xfd;TL1=0xfd;SM0=0;SM1=1;REN=1; //控制RITR1=1;/*以上为定时器设置和波特率设置,这样的话,通过串口调试助手发送数据(随意数据)通过改变RI(串口接收标志来实现继电器的吸合与打开*/while(1){if(RI==1){RI=0;delay(500);RELAY=!RELAY; //如果吸合则打开,如果己打开则吸合.}}}以上在AT89s52+Keil上编译调试运行OK。
/****************************************************************************//*电子日历,有时间显示、闹铃、日期、秒表及键盘设置功能*//*功能键A: 设置位数字+1 闹钟模式下为闹钟开关秒表模式下为记时开关*//* 功能键B:设置位数字—1 闹钟模式下为闹钟开关*//* 功能键C:设置模式及设置位选择秒表模式下为清零键*//*功能键D:在四种工作模式下切换设置闹钟开关*//****************************************************************************/#include#include/***************这里设置程序初始化时显示的时间****************/#define SET_HOUR 12 /*设置初始化小时*/#define SET_MINUTE 00 /*设置初始化分钟*/#define SET_SECOND 00 /*设置初始化秒数*//*************************系统地址****************************/#define BASE_PORT 0x8000 /*选通基地址*/#define KEY_LINE BASE_PORT+1 /*键盘行线地址*/#define KEY_COLUMN BASE_PORT+2 /*键盘列线地址*/#define LED_SEG BASE_PORT+4 /*数码管段选地址*/#define LED_BIT BASE_PORT+2 /*数码管位选地址*/#define LED_ON(x) XBYTE[LED_BIT]=(0x01〈〈x) style=”line—height: 25px; ”> #define LED_OFF XBYTE[LED_SEG]=0x00 /*LED显示空*/</x) >/**************在设置模式下对秒分时的宏定义*****************/#define SECOND 0 /*对应数码管右边两位*/#define MINUTE 1 /*对应数码管中间两位*/#define HOUR 2 /*对应数码管左边两位*//********************定义四种工作模式***********************/#define CLOCK clockstr /*时钟模式*/#define ALART alartstr /*闹钟模式*/#define DATE datestr /*日期模式*/#define TIMER timerstr /*秒表模式*//****************以下是所有子函数的声明*********************/void sys_init(void); /*系统的初始化程序*/void display(void); /*动态刷新一次数码管子程序*/void clockplus(void); /*时间加1S的子程序*/void update_clockstr(void); /*更新时间显示编码*/void update_alartstr(void);/*更新闹钟时间的显示编码*/void update_datestr(void); /*更新日期显示编码*/void update_timerstr(void);/*更新秒表时间的显示编码*/void deley(int); /*延时子程序*/void update_dispbuf(unsigned char *); /*更新显示缓冲区*/unsigned char getkeycode(void); /*获取键值子程序*/void keyprocess(unsigned char); /*键值处理子程序*/unsigned char getmonthdays(unsigned int,unsigned char);/*计算某月的天数子程序*//*功能键功能子函数*/void Akey(void); /*当前设置位+1 开关闹钟开关秒表*/void Bkey(void);/*当前设置位—1 开关闹钟*/void Ckey(void); /*设置位选择秒表清零*/void Dkey(void);/*切换四种工作模式*//**********************全局变量声明部分*********************/unsigned char led[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};/*从0~9的LED编码*/unsigned char ledchar[3]={0x5c,0x54,0x71};/*o n f*///unsigned char key[24]={ /*键值代码数组对应键位:*/// 0x70,0x71,0x72,0x73,0x74,0x75, /*7 8 9 A TRACE RESET*/// 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, /* 4 5 6 B STEP MON */// 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, /* 1 2 3 C HERE LAST */// 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5}; /* 0 F E D EXEC NEXT */struct{ /*时间结构体变量*/unsigned char s;unsigned char m;unsigned char h;}clock={SET_SECOND,SET_MINUTE,SET_HOUR};struct{ /*闹铃时间结构体变量*/unsigned char m;unsigned char h;}alart={SET_MINUTE,SET_HOUR};struct{ /*日期结构体变量*/unsigned int year;unsigned char month;unsigned char day;}date={6,1,1};struct{/*秒表时间结构体变量*/unsigned char ms;unsigned char s;unsigned char m;}timer={0,0,0};unsigned char dispbuf[6]; /*显示缓冲区数组*/unsigned char clockstr[6]; /*时间显示的数码管编码数组*/unsigned char alartstr[6]; /*闹钟显示的数码管编码数组*/unsigned char datestr[6]; /*日期显示的数码管编码数组*/unsigned char timerstr[6];/*秒表显示的数码管编码数组*/unsigned int itime=0,idot; /*定时器0中断计数*/unsigned char itime1=0; /*定时器1中断计数*/sbit P3_1=P3^1; /*外接蜂鸣器的管脚*/bdata bit IsSet=0; /*设置模式标志位0:正常走时1:设置模式*/bdata bit Alart_EN=0; /*闹铃功能允许位0:禁止闹铃1:允许闹铃*/bdata bit IsBeep=0;/*响铃标志位0:未响铃1:正在响铃*/unsigned char SetSelect=0; /*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/unsigned char *CurrentMode;/*标志当前正设置的功能,如CurrentMode=CLOCK 或CurrentMode=ALART等*/void timerplus(void);/**************************函数部分*************************/void main(void){sys_init();while(1){XBYTE[KEY_COLUMN,0x00]; /*给键盘列线赋全零扫描码,判断是否有键按下*/while((XBYTE[KEY_LINE]&0x0f)==0x0f) /*检测是否有键按下,无则一直进行LED 的刷新显示*/{if(Alart_EN&&(clock.h==alart。
STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码
STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码STC 51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码原文:(改自周立功软件包)#include <reg51.h>#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned intextern void Delay1us(unsigned char );sbit SDA=P1^6; /*模拟I2C数据传送位*/sbit SCL=P1^7; /*模拟I2C时钟控制位*/bit ack; /*应答标志位*//************************************************************** *****起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.*************************************************************** *****/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/Delay1us(1);SCL=1;Delay1us(5); /*起始条件建立时间大于4.7us,延时*/SDA=0; /*发送起始信号*/Delay1us(5); /* 起始条件锁定时间大于4μs*/SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay1us(2);}/************************************************************** *****结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.*************************************************************** *****/void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/Delay1us(1); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4us*/Delay1us(5);SDA=1; /*发送I2C总线结束信号*/Delay1us(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
详解一个电脑串口控制单片机驱动继电器的例子(全部源代码)
开源详解(看完如觉得不错,请顶一下哦!)声明:软件版权归作者完全所有。
未经作者授权,请勿在任何第三方杂志、报刊、网站转载或发表,本程序仅供学习研究用,您可以自由拷贝、散发本程序,但不能用于商业目的。
很多网上认识的朋友,提到这个话题,在此用此例给热爱单片机的朋友!---一个简单的串口控制继电器的例子(全部源代码)-- 马工2006-5-8 20:00下面的文章详细的说明了如何在PC端编制控制程序,并且通过串口输出数据来控制单片机硬件,单片机外围连接了若干继电器,达到控制继电器开关的作用。
要说的是,有很多的方法可以实现上述的功能,下面的方法只是其中的一种,并且出于便于大家学习阅读的目的,很多代码并没有进行优化,而是将其展开编写,在你理解后,你完全可以在此基础上修改、优化代码,使之更优化和精简,并符合你的其他要求。
如果你读完这篇文章,觉得给你带来了帮助,我非常高兴。
如果你无法理解,你应该再看一下其他更基础的书籍、文章。
我想应该分成二个部分来讲(单片机部分、PC程序部分),并且希望能写得较为详细,把基础的讲述清楚。
1、单片机部分电路图:此主题相关图片如下:单片机源代码(asm格式):;--------------------------------------------------;--------------------------------------------------;设置串行口波特率9600;串行口设置MODE1,SM1=0,REN=1,SMOD=1;晶振11.0592,定时设置为0FDH;常用端口设置参数;FD 9600;FA 4800;F4 2400;E8 1200;--------------------------------------------------;*********************************************************** ORG 00HJMP STARTORG 23HJMP UARTORG 30HSTART: MOV SP,#70HMOV SCON,#50HMOV TMOD,#00100001B ;TIM1在模式2 TIM0在模式1MOV TH1,#0F4H ;设置定时时间SETB TR1 ;启动定时器1SETB ES ;允许串口中断SETB EA ;允许总中断MOV P0,#0 ;P0、P2输出低电平MOV P2,#0JMP $ ;等待状态;*****************************************;串行口中断;*****************************************UART: PUSH ACCPUSH PSWCLR ES ;关闭串行口中断MOV TH0,#HIGH(65536-65536)MOV TL0,#LOW(65536-65536)SETB TR0 ;开定时器0MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位MOV R0,#30HREC:jbc tf0,FS ;接收时间是否超时?是则执行FSJNB RI,REC ;接收数据CLR RIMOV A,SBUFMOV @R0,AINC R0JMP RECFS: CLR TR0 ;关定时器0;********************************CALL FUN ;解码并控制继电器SETB ES ;开串行口中断POP PSWPOP ACCRETI ;中断子程序返回;**************************************** ;解码并控制继电器;下面的程序可以更简洁,但为了方便,展开来编制;**************************************** FUN: MOV A,#0AH ;判断第1字节即同步位CJNE A,30H,ERRMOV A,#0DH ;判断第4字节即结束位CJNE A,33H,ERR;****************************************;第2字节即数据位1,代表继电器J1-8;第3字节即数据位2,代表继电器J9-16;**************************************** MOV A,31HMOV P0,AMOV A,32HMOV P2,ARET;**************************************; 数据错误处理;************************************** ERR:MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位RETEND ;程序结束;--------------------------------------------------;--------------------------------------------------单片机源代码(asm格式)+电路图下载:点击浏览该文件电路图说明:这个电路非常典型,串行口(也称RS232)接口集成电路MAX232与单片机AT89S51引脚P3.0(RXD)\P3.1(TXD)连接,构成与主机的通讯接口电路。
51单片机C语言源代码例程附带电路图
闪烁灯[实验要求]点亮与单片机P1.0口相连的发光二极管,延时0.2S,然后熄灭,延时0.2S,再点亮,如此循环下去。
[实验目的]初步了解单片机IO口输出高低电平的作用,延时函数的时间估算。
[硬件电路][源代码]#include<reg51.h>/**********************************************************上面这行是一个"文件包含"处理。
所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。
大家可以在编译器目录下面用记事本打开这个文件看看。
*********************************************************/sbit P1_0=P1^0; //定义IO口这步的目的是让编//译器知道P1_0代表的就是单片机的P1.0口void delay02s(void) //延时0.2秒子程序{unsigned char i,j,k; //定义3个无符号字符型变量。
for(i=20;i>0;i--) //三个FOR循环用来延时,这里为for(j=20;j>0;j--) //什么是0.2S大家可以用WAVE for(k=248;k>0;k--); //高断点仿真一下,就可知道大概 } //是0.2S了。
void main(void) //每一个C语言程序有且只有一个主函数,{while(1) //循环条件永远为真,以下程序一直执行下去。
{P1_0=0; // I/O口P1.0输出低电平,小灯被点亮。
delay02s(); //延时经过0.2秒。
P1_0=1; // I/O口P1.0输出高电平,小灯熄灭。
51单片机C语言程序设计-图文
/* 名称:8 只 LED 左右来回点亮 说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果
*/ #include<reg51.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int //延时 void DelayMS(uint x) {
case 2: //东西向黄灯闪烁,绿灯关闭 DelayMS(300); YELLOW_A=~YELLOW_A;GREEN_A=1; if(++Flash_Count!=10) return; //闪烁 5 次 Flash_Count=0; Operation_Type=3; break;
case 3: //东西向红灯,南北向绿灯亮 RED_A=0;YELLOW_A=1;GREEN_A=1; RED_B=1;YELLOW_B=1;GREEN_B=0; DelayMS(2000); Operation_Type=4; break;
3 Ykcsh 呈献
0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff }; //延时 void DelayMS(uint x) {
uchar i; while(x--) {
for(i=0;i<120;i++); } } //主程序 void main() { uchar i; while(1) { //从数组中读取数据送至 P0 和 P2 口显示
uchar i; while(x--) {
for(i=0;i<120;i++); } } //主程序 void main() { uchar i; P2=0x01; while(1) {
单片机控制继电器实现开关状态显示
单片机控制继电器实现开关状态显示单片机是一种集成电路,其中包含了处理器、存储器、定时器和I/O 端口等多种功能模块。
通过编写程序,可以控制单片机的各种功能,从而实现各种应用需求。
继电器是一种电器元件,可将小电流控制大电流的开关,常用于电力系统中。
在实际应用中,我们经常需要通过单片机来控制继电器的开关状态,并且需要实时显示继电器的状态。
下面将介绍如何利用单片机来实现这一功能。
首先,我们需要选择适合的单片机芯片。
常见的单片机芯片有51系列、AVR系列、STM32系列等。
在此我们以51系列的STC89C52为例进行说明。
这是一种常见的8位单片机,具有较强的功能和性价比。
接下来,我们需要连接继电器和单片机。
将单片机的IO口和继电器的控制端连接,通过控制IO口的高低电平信号来控制继电器的开关。
同时,我们还需要将继电器的状态通过LED等方式进行实时显示。
接下来,我们需要编写单片机的程序来实现控制继电器和显示继电器状态的功能。
我们可以使用C语言或者汇编语言来编写程序。
以下是一个示例的C语言程序:```c#include <reg52.h>sbit relay = P1^0; // 继电器IO口sbit led = P1^1; // LED IO口void delay(unsigned int ms) // 延时函数while (ms--)unsigned char i, j;for (i = 0; i < 10; i++)for (j = 0; j < 110; j++);}}void mainunsigned char switchStatus = 0; // 开关状态变量,0表示关闭,1表示打开while (1)if (switchStatus == 0) // 如果开关状态为关闭,则打开继电器并点亮LEDrelay = 1; // 继电器吸合led = 1; // LED点亮switchStatus = 1; // 更新开关状态为打开}else // 如果开关状态为打开,则关闭继电器并熄灭LEDrelay = 0; // 继电器断开led = 0; // LED熄灭switchStatus = 0; // 更新开关状态为关闭}delay(1000); // 延时1秒}```以上程序的逻辑很简单,当开关状态为关闭时,继电器吸合并点亮LED;当开关状态为打开时,继电器断开并熄灭LED。
51单片机C语言编程100例
51单片机C语言编程100例1. 前言在学习嵌入式系统开发中,单片机是必不可少的一个组成部分。
而在单片机的编程语言中,C语言因其易学易用、灵活性高等特点而备受青睐。
本文将介绍51单片机C语言编程的100个实例,旨在帮助读者更加深入地理解和掌握这一领域的知识。
2. 闪烁LED灯实例1:使用51单片机编程控制一个LED灯的闪烁,实现简单的开关控制。
3. 延时程序实例2:编写一个延时程序,用于控制LED灯的延时亮灭,实现不同频率的闪烁效果。
4. 数码管显示实例3:通过编写程序,使用数码管显示数字0-9,实现简单的计数功能。
5. 矩阵键盘输入实例4:通过编程实现对矩阵键盘的输入检测和处理,实现对不同按键的响应。
6. PWM输出实例5:使用51单片机的PWM输出功能,控制LED灯的亮度调节。
7. 温度传感器读取实例6:通过温度传感器读取模块,实现温度的检测和显示。
8. 模拟信号采集实例7:通过编程实现对模拟信号的采集和处理,实现对外部信号的监测和控制。
9. 串口通信实例8:使用51单片机的串口通信功能,实现单片机与计算机之间的数据传输。
10. 蜂鸣器控制实例9:通过编程控制蜂鸣器的开关,实现不同频率的声音发声。
11. 数字口输入检测实例10:通过编程实现对数字口输入状态的检测和处理,实现对外部信号的监测和控制。
12. 定时器中断实例11:使用51单片机的定时器中断功能,实现定时任务的执行和控制。
13. PWM输出调制实例12:使用数字口和定时器实现PWM波形的调制和输出控制。
14. 蓝牙通信实例13:通过蓝牙模块实现51单片机与手机之间的数据通信,实现简单的远程控制。
15. 温湿度传感器读取实例14:通过温湿度传感器读取模块,实现温湿度的检测和显示。
16. 步进电机控制实例15:通过编程控制步进电机的转动和方向,实现简单的运动控制。
17. 超声波测距实例16:通过超声波测距模块,实现对距离的检测和显示。
18. 电机驱动控制实例17:通过编程和电机驱动模块,实现电机的转动和速度控制。
51单片机汇编语言及C语言经典实例解析
51单片机汇编语言及C语言经典实例实验及课程设计一、闪烁灯如图1 所示为一简单单片机系统原理图:在P1.0 端口上接一个发光二极管L1,使L1 在不停地一亮一灭,一亮一灭的时间间隔为0.2 秒。
延时程序的设计方法,作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2 秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:如图4.1.1 所示的石英晶体为12MHz,因此,1 个机器周期为 1 微秒,机器周期微秒如图 1 所示,当P1.0 端口输出高电平,即P1.0=1 时,根据发光二极管的单向导电性可知,这时发光二极管L1 熄灭;当P1.0 端口输出低电平,即P1.0=0 时,发光二极管L1 亮;我们可以使用SETB P1.0 指令使P1.0端口输出高电平,使用CLR P1.0 指令使P1.0 端口输出低电平。
C 语言源程序#include <AT89X51.H>sbit L1=P1^0;void delay02s(void) //延时0.2 秒子程序{unsigned char i,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}void main(void){while(1){L1=0;delay02s();L1=1;delay02s();}汇编源程序ORG 0START: CLR P1.0LCALL DELAYSETB P1.0LCALL DELAYLJMP START DELAY: MOV R5,#20 ;延时子程序,延时0.2 秒D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND图2 程序设计流程图图1 单片机原理图二、多路开关状态指示如图 3 所示,AT89S51 单片机的 P1.0-P1.3 接四个发光二极管 L1-L4,P1.4-P1.7 接了四个开关 K1-K4,编程将开关的状态反映到发光二极管上。
C8051F系列单片机串口通讯程序
C8051F系列单片机串口通讯程序C8051F系列单片机串口通讯程序采用C8051F020单片机//串口编程--接收PC发过来的字符串,回发字符串.发送期间中断控制LED灯闪烁//采用外部晶振22.1184MHz 使用定时器1,方式2产生波特率,SMOD = 0或者 1 //定时器初值X=256-SYSCLK*(SMOD+1)/(BAUDRATE*384)/#includesfr16 TMR3RL = 0x92; //定时器3重装载寄存器sfr16 TMR3 = 0x94; //定时器3计数器#define uchar unsigned char#define uint unsigned int//----------------------------------------------------------------------//参数设置区//----------------------------------------------------------------------#define BAUDRATE 4800 //波特率bps#define CLKOUT 22118400 //外部晶振,修改也要修改OSCXCN #define SMODVAL 0 //SMOD的值,修改请也修改PCONVAL#define PCONVAL 0x00 //PCON的值,=0x00时SMOD0=0; =0x80时SMOD0=1 #define TXVAL (256-CLKOUT*(SMODVAL+1)/BAUDRATE/384) //定时器初值#define MAX_LEN 10 //每次接收/发送字符串的长度//---------------------------------------------------------------------//全局变量//---------------------------------------------------------------------sbit LED = P1^6; //LED '1'亮'0'灭bit readFlag = 0; //读标志uchar readCounts = 0; //已经读取的字符个数,与MAX_LEN比较uchar idata trdata[MAX_LEN]; //要接收/发送的字符串//----------------------------------------------------------------------//子函数声明//---------------------------------------------------------------------- void SYSCLK_Init(void); //系统时钟初始化void PORT_Init(void); //端口初始化void UART0_Init(void); //串口UART0初始化void Send_Char(uchar ch); //发送单个字符void Send_String(uchar * str, uint len); //发送一个字符串void UART0_ISR(); //串口中断服务程序,接收字符void Timer3_Init(uint counts); //定时器3初始化void Timer3_ISR(void); //定时器3中断服务程序//---------------------------------------------------------------------- //主函数//---------------------------------------------------------------------- void main(void){WDTCN = 0xde; //禁止看门狗WDTCN = 0xad;SYSCLK_Init(); //时钟初始化PORT_Init(); //端口初始化UART0_Init(); //串口初始化Timer3_Init(CLKOUT/12/10); //定时器初始化EA = 1; //开全局中断while(1){if(readFlag) //已经读取{readFlag = 0; //清零Send_String(trdata,MAX_LEN); //发送字符串}}}//----------------------------------------------------------------------//子函数具体实现//----------------------------------------------------------------------//系统时钟初始化void SYSCLK_Init(void){uint i;OSCXCN = 0x67; //采用外部晶振22.1184MHz,不分频. 选型OSCXCN=0110,0111 for(i=0;i<256;i++); //等待>1mswhile(!(OSCXCN&0x80)); //查询直到XTLVLD=1,晶振稳定OSCICN = 0x88; //切换到外部振荡器,允许时钟失效监测器. OSCICN=1000,1000 }//端口初始化void PORT_Init(void){XBR0 = 0x04; //允许UART0,RX,TX连到2个端口引脚. XBR0=0000,0100XBR1 = 0x00;XBR2 = 0x40; //交*开关使能P0MDOUT |= 0x03; //P0.0为推拉方式输出,即TX0,RX0所在的端口0000,0011P1MDOUT |=0x40; //P1.6为推拉方式输出,即LED所在的端口0100,0000}//串口初始化void UART0_Init(void){SCON0 = 0x50; //选择串口方式1,波特率可变SCON0=0101,0000TMOD = 0x20; //选择T1,方式2,自动再装入8位计数器TH1 = (int)TXVAL; //T1初值,根据波特率,时钟等计算. 0xF4, bps=4800bpsTL1 = (int)TXVAL;ES0 = 1; //UART0中断开启TR1 = 1; //启动定时器T1PCON |= PCONVAL; //PCON=0x00,SMOD = 0 ; PCON=0x80,SMOD=1 TI0 = 1; //声明TX0就绪,可以发送TR0 = 1;}//定时器初始化void Timer3_Init(uint counts){TMR3CN = 0x00; //禁止定时器T3,清TF3,采用SYSCLK/12为时基TMR3RL = -counts; //初始化重装载值TMR3 = 0xffff; //设置为立即重装载EIE2 |= 0x01; //T3中断开启TMR3CN |= 0x04; //启动T3}//发送单个字符void Send_Char(uchar ch){SBUF0 = ch; //送入缓冲区while(TI0 == 0); //等待发送完毕TI0 = 0; //软件清零}//发送字符串,调用Send_Char() len字符串长度void Send_String(uchar * str,uint len){uint k = 0;do{Send_Char(*(str + k));k++;} while(k < len);}//定时器3中断服务程序void Timer3_ISR(void) interrupt 14 using 0 {TMR3CN &= ~(0x80); //清TF3LED = ~LED;}//UART0中断服务程序. 接收字符void UART0_ISR(void) interrupt 4 using 1 {uchar rxch;if(RI0) //中断标志RI0=1 数据完整接收{RI0 = 0; //软件清零rxch = SBUF0; //读缓冲if(readCounts>=MAX_LEN){readCounts = 0;readFlag = 1;}trdata[readCounts] = rxch; //存入数组,供发送readCounts++;}}//------------------------------------------------------------- //程序结束。
51单片机C语言程序设计源代码
新概念51单片机C语言教程----入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27)#include <reg52.h> //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{led1=0; /*点亮第一个发光二极管*/}例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39)#include <reg52.h> //52系列单片机头文件void main() //主函数{P1=0xaa;//while(1);}例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);led1=1; /*关闭第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);}}- 2 -例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
(part2_4.c P48)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/delay1s(); //调用延时子函数led1=1; /*关闭第一个发光二极管*/delay1s(); //调用延时子函数}}void delay1s() //子函数体{uint i,j;for(i=500;i>0;i--)for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。
C51单片机串口通讯通用模块代码(可用于操作系统串口通讯)
C51单片机串口通讯通用模块代码(可用于操作系统串口通讯)#include#include "UART1.h"#include "commdriver.h"//当前适用于C51//可以根据具体CPU型号,修改宏定义和串口初始化代码就可以#define CPU_XTAL 22118400 //CPU频率#define FUNCTION_NULL 0 //没有定义函数#define COM_TI TI //发送中断寄存器#define COM_TI0() {TI = 0;} //发送中断寄存器清零#define COM_TI1() {TI = 1;} //发送中断寄存器置一( 强行置一触发发送中断)#define COM_TI_SBUF(dat) {SBUF = dat;} //发送数据到硬件缓冲区#define COM_TI_End() {return;} //发送结束处理函数#define COM_RI RI //接收中断寄存器#define COM_RI0() {RI = 0;} //接收中断寄存器清零#define COM_RI1() {RI = 1;} //接收中断寄存器置一#define COM_RI_SBUF(dat) {dat = SBUF;} //提取接收硬件缓冲区数据#define COM_TI_FLAG COM_TI //发送中断标志寄存器(非中断发送方式使用)#define COM_TI_FLAG0() COM_TI0() //发送中断标志寄存器清零(非中断发送方式使用)void (*COM1RevEvent)(unsigned char dat); //数据接收事件#define LenTxBuf 30 //发送缓冲区长度#define LenRxBuf 1 //接收缓冲区长度volatile unsigned char TxBuf1[LenTxBuf],RxBuf1[LenRxBuf]; //收发缓冲区实体volatile unsigned char *inTxBuf1,*outTxBuf1,*inRxBuf1,*outRxBuf1; //收发缓冲区读写指针volatile unsigned char TIflag1=1;//Note:It must be 1. //发送缓冲区为空标志//*********************#define _TxBuf TxBuf1#define _RxBuf RxBuf1#define _inTxBuf inTxBuf1#define _outTxBuf outTxBuf1#define _inRxBuf inRxBuf1#define _outRxBuf outRxBuf1#define _TIflag TIflag1/*************函数声明****************/#define _COMRevEvent COM1RevEvent //串口接收事件#define _USART_IRQ void USART1_IRQHandler(void) interrupt 4 //串口中断服务程序#define _COM_Buffer_Init void COM1_Buffer_Init(void) //串口缓冲区初始化#define _COM_Open void COM1_Open(unsigned int baudrate,void (*revevent)(unsigned char dat)) // 串口初始化#define _COM_Close void COM1_Close(void) //关闭串口#define _COM_GetOneByte unsigned charCOM1_GetOneByte(unsigned char *ch) //获取一个字节#define _COM_GetPChar unsigned char COM1_GetPChar(unsigned char *ch,unsigned char len) //获取指定长度字节数组#define _COM_RxByte unsigned char COM1_RxByte(void) //获取接收字节个数//********缓冲区中断方式发送(安全性高)#define _COM_SendOneByte unsigned char COM1_SendOneByte(unsigned char one_byte) // 发送一个字节#define _COM_SendPChar void COM1_SendPChar(unsigned char *P,unsigned char Len) //发送定长字节数组#define _COM_SendString void COM1_SendString(unsigned char *P) //发送字符串//********非缓冲区中断方式发送#define _COM_PrintOneByte void COM1_PrintOneByte(unsigned char c) // 发送一个字节#define _COM_PrintPChar void COM1_PrintPChar(unsigned char *buf,unsigned int len) //发送定长字节数组#define _COM_PrintString void COM1_PrintString(unsigned char *P) //发送字符串//*************内部引用模型函数(外部不关心,移植时修改后面函数名,要与上面对应的外部声明的函数名一致)*******************#define COM_GetOneByte_(ptr) COM1_GetOneByte(ptr) //与上面获取一个字节的函数对应#define COM_SendOneByte_(dat) COM1_SendOneByte(dat) //与上面发送一个字节的函数对应#define COM_PrintOneByte_(dat) COM1_PrintOneByte(dat) //与上面发送一个字节的函数对应//*********************函数模型定义区(不需要修改)*****************/****************************函数模型:void USART_IRQHandler(void)函数功能:串口中断服务程序入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_USART_IRQ //串口1中断{volatile unsigned char *t;if(COM_RI){COM_RI0(); //清接收标记if(_COMRevEvent != FUNCTION_NULL) //自定义接收事件{COM_RI_SBUF(*_inRxBuf);_COMRevEvent(*_inRxBuf);}else{t = _inRxBuf;t++;if(t == (_RxBuf + LenRxBuf)) t = _RxBuf;if(t != _outRxBuf) //RxBuf No Full{COM_RI_SBUF(*_inRxBuf);_inRxBuf = t;}}}if(COM_TI){COM_TI0();if(_inTxBuf == _outTxBuf) {_TIflag = 1;COM_TI_End();};//TxBuf1 EmptyCOM_TI_SBUF(*_outTxBuf); _outTxBuf++;if(_outTxBuf == (_TxBuf+LenTxBuf)) _outTxBuf = _TxBuf;}}/****************************函数模型:void COM1_Buffer_Init(void)函数功能:串口1缓冲区初始化入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Buffer_Init{_inTxBuf = _TxBuf;_outTxBuf = _TxBuf;_inRxBuf = _RxBuf;_outRxBuf = _RxBuf;}/****************************函数模型:void COM_Open(unsigned int baudrate,void (*revevent)(unsigned char dat))函数功能:系统串口初始化入口参数: unsigned int baudrate:串口波特率返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Open{//定时器1做波特率发生器TI = 0; /* clear transmit interrupt */TR1 = 0; /* stop timer 1 */ET1 = 0; /* disable timer 1 interrupt */PCON |= 0x80; /* 0x80=SMOD: set serial baudrate doubler */ TMOD &= ~0xF0; /* clear timer 1 mode bits */TMOD |= 0x20; /* put timer 1 into MODE 2 */TH1 = (unsigned char) (256 - (CPU_XTAL / (16L * 12L * baudrate)));TR1 = 1; /* start timer 1 *///设置串口1模式SM0 = 0; SM1 = 1; /* serial port MODE 1 */SM2 = 0;REN = 1; /* enable serial receiver */RI = 0; /* clear receiver interrupt */TI = 0; /* clear transmit interrupt */ES = 1; /* enable serial interrupts */PS = 1; /* set serial interrupts to low priority */_COMRevEvent = revevent;}/****************************函数模型:void COM1_Close(void)函数功能:关闭系统串口入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Close{}/****************************函数模型:unsigned char COM1_GetOneByte(unsigned char *ch)函数功能:获取一个字节入口参数:unsigned char *ch:接收字节指针返回值: unsigned char *ch:接收字节指针unsigned char :获取状态;0:成功,1:失败(缓冲区为空)修改者:修改时间:修改内容简要:***************************/_COM_GetOneByte{if(_inRxBuf == _outRxBuf) {return 0;}; //RxBuf Empty*ch = *_outRxBuf; _outRxBuf++;if(_outRxBuf==_RxBuf+LenRxBuf) _outRxBuf = _RxBuf;return 1;}/****************************函数模型:unsigned char COM_GetPChar(unsigned char *ch,unsigned char len)函数功能:获取指定长度字节数组入口参数: unsigned char *ch:接收字节数组指针unsigned char len:接收字节个数返回值: unsigned char *ch:接收字节数组指针unsigned char:实际接收字节个数修改者:修改时间:修改内容简要:***************************/_COM_GetPChar{unsigned char i = 0;do{len--;if(!COM_GetOneByte_(ch)) break;i++;ch++;}while(len);return i;}/****************************函数模型:unsigned char COM_RxByte(void)函数功能:获取接收缓冲区有效字节个数入口参数:无返回值: unsigned char:接收缓冲区有效字节个数修改者:修改时间:修改内容简要:***************************/_COM_RxByte{if(_inRxBuf>=_outRxBuf) return (_inRxBuf-_outRxBuf);else return LenRxBuf-(_outRxBuf-_inRxBuf);}/****************************函数模型:unsigned char COM_SendOneByte(unsigned char one_byte)函数功能:发送一个字节入口参数: unsigned char one_byte:发送的字节返回值:unsigned char:发送状态,0:成功,1:失败(缓冲区满)修改者:修改时间:修改内容简要:***************************/_COM_SendOneByte{volatile unsigned char *t;if(_TIflag){_TIflag = 0;COM_TI1();}t = _inTxBuf;t++;if(t == _TxBuf + LenTxBuf) t = _TxBuf;if(t == _outTxBuf) {return 1;};//TxBuf Full*_inTxBuf = one_byte;_inTxBuf = t;return 0;}/****************************函数模型:void COM_SendPChar(unsigned char *P,unsigned char Len)函数功能:发送定长字节数组入口参数: unsigned char *P:字节数组指针unsigned char Len:发送长度返回值:无修改者:修改时间:修改内容简要:***************************/_COM_SendPChar{while(Len){//while(COM1_SendOneByte(*P)); //发送失败,继续发送,知道发送成功COM_SendOneByte_(*P);P++;Len--;}}/****************************函数模型:void COM_SendString(unsigned char *P)函数功能:发送字符串入口参数: unsigned char *P:字符串指针返回值:无修改者:修改时间:修改内容简要:***************************/_COM_SendString{while(*P){COM_SendOneByte_(*P);P++;}}//**************** 非缓冲区中断方式发送/****************************函数模型:void COM_PrintOneByte(unsigned char c)函数功能:发送一个字节入口参数: unsigned char one_byte:发送的字节返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintOneByte{COM_TI_FLAG0();COM_TI_SBUF(c); //发送数据while(!COM_TI_FLAG) ; //等待发送结束}/****************************函数模型:void COM_PrintPChar(unsigned char *buf,unsigned int len)函数功能:发送定长字节数组入口参数: unsigned char *P:字节数组指针unsigned char Len:发送长度返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintPChar{while(len){COM_PrintOneByte_(*buf);buf ++;len--;}}/****************************函数模型:void COM_PrintString(unsigned char *P) 函数功能:发送字符串入口参数: unsigned char *P:字符串指针返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintString{while(*P){COM_PrintOneByte_(*P);P++;}}。
我的51单片机之 MAX485的 C语言与汇编的编程
//与自制软件 ComTest 通信,设好通信口,按下软件中相应按钮,数码管显示相应值
//made by luqichao
//************************************************************************
#include <reg51.h>
;
{ 0 , 1, 2 , 3 , 4 , 5, 6, 7, 8, 9 }
MAIN:
MOV SCON,#50H; 串口工作于方式 1,充许接收
MOV PCON,#0H;
波特率不倍增
MOV TMOD,#20H; 定时器计数器 1 工作于方式 2;
MOV TH1,#0FDH;
MOV TL1,#0FDH; 波特率为 9600;
LEDCODE EQU P1 ComData EQU 40H; LED1 EQU P0.6; LED2 EQU P0.7; M485 EQU P0.5;
//作为收发数据的使能短,1 为发数据 0 为收数据
;字形码:0--f 及小数点
AscLed:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;
四、汇编程序: ;************************************************************************** ;与自制软件 ComTest 通信,设好通信口,按下软件中相应按钮,数码管显示相应值 ;made by luqichao ;************************************************************************** ORG 0000H AJMP MAIN ORG 001BH AJMP T1P ORG 0023H AJMP COMM ORG 0030H
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
while(1) {
if(RI==1) { RI=0; delay(500); RELAY=!RELAY; 己打开则吸合。 }
}
//如果吸合则打开,如果
} 以上在 AT89s52+Keil 上编译调试运行 OK。
//定义继电器:接 P1^1
void delay(unsigned int cnt) { while(--cnt); }
main() {
TMOD=0x20;
//
TH1=0xfd;
TL1=0xfd;
SM0=0;
SM1=1;
REN=1; //控制 RI
TR1=1;
/*以上为定时器设置和波特率设置,这样的话,通过串口调试助手发送数据(随 意数据)通过改变 RI(串口接收标志来实现继电器的吸合与打开 */
51 单片机串口控制继电器的 C 源程序 2009-09-29 23:13 计算机通过软件来控制单片机继电器。
操作:计算机使用串口调试助手,当然,可以自己编写控制软件(上位机软件)。 单片机 P1.1 口连上继电器
C 源程序为:
#include <reg52.h>