整理电脑里面资料的时候,发现以前大二结束的时候写的一个小项目,贴出来吧,回味下曾经倒腾硬件方面的日子,那些年和几个小伙伴一起逛电子商城,边吐槽玩硬件就是烧钱,还时不时的往那跑,用Altium Designer 画电路图和PCB图,一起大热天的手持电烙铁焊板子,拿着万用表测电压,接着串口线板级调试程序。现在回想起来觉得也挺充实的,转眼间研究生三年又要过去了,以后工作了,回想起研究生的生活也应该是这样子吧。
这个小项目是基于51单片机的,电子类专业孩子的入门玩意。实现一个多任务的控制系统,采用模块化编程,通过键盘输入控制读取电压,环境温度值,时间等基本功能。开发环境 Keil 4。
51单片机作为入门级,后面陆续接触了ARM和FPGA,主要是FPGA,当时用的开发软件是Altea 公司的 Quartus II,用 Verilog HDL 编写,用的芯片是 Altera 公司的 Cyclone II,后来由于实习和考研,就没倒腾FPGA了,中间由于某些原因,想走软件这条路,又重新拾起了C/C++,汇编语言,微机原理,数据结构和基本算法等,而后开始学习 Linux,回想起来,要是一开始是学ARM,不是FPGA,恐怕那时候早就接触Linux了,FPGA就当扩展下视野吧。硕士阶段主要是软件开发了,可以说是没碰过这些硬件了,研究方向是图像处理。额外之余研究下了计算机网络(TCP/IP),Linux 内核(很浅)。并研究了一些开源项目,开源代码,如 STL,Linux Kernel(网络栈),TinyHTTPd 等。一路走来有硬件也有软件。至于哪个好玩些,硬件调试成功,和软件编译无bug带来的感觉是一样一样的,硬件那部分也要写程序。
main.c
/***************************************************************************************************
**----------------历史版本信息----------------------------------------------------------------------
**创建人:**
**版 本:v0.1
**日 期:2011年8月
**描 述:基于前后台的PC机控制系统
** 平台:PL-51单片机控制系统,晶振为11.0592MHZ
**
**-----------------功能描述-------------------------------------------------------------------------
**
** 本设计为——基于前后台的PC机控制系统。
** 该系统可以通过超级终端控制LED的亮灭,蜂鸣器唱歌及报警,
** 控制DS18B20读取当前环境温度并显示在超级终端和LCD1602上,
** 控制数码管连续显示相应终端输入数字,
** 控制DS1302读取当前时间并显示在LCD1602上,可通过终端修改当前时间,
** 具备整点报时,闹钟提醒功能,并将闹钟状态显示在LCD1602上,
** 控制ADC0804读取测点电压值,并显示在终端上,
** 该系统支持终端可退格输入操作,//并支持可在线计算功能(简易计算器)(该功能待完善)。
**
**-----------------当前版本修订---------------------------------------------------------------------
**修改人:
**版 本:
**日 期:
**描 述:
**
**--------------------------------------------------------------------------------------------------
***************************************************************************************************/
#include"terminal.h"
#include"beep.h"
void main(void)
{
Init_Terminal();
Terminal_Temper();
while (1)
{
Terminal();
}
}
terminal.h
#ifndef __TERMINAL_H__
#define __TERMINAL_H__
void Init_Terminal(void);
void Send(char *add);
void Sendbyte(char dat);
void Rec_Terminal(char size);
void Clear_Terminal(char size);
void Terminal(void);
void Terminal_Temper(void);
void Help(void);
void Display_Terminal(void);
void Wenqian(void);
void Reboot(void);
void Clear(void);
void Buzzer_Timer(void);
void Buzzer_Music(void);
void Buzzer_Time(void);
void Temper_Display(void);
void Dataled_On(void);
void Dataled_Off(void);
void Led_On(void);
void Led_Off(void);
void Compute_Terminal(void);
void Terminal_Voltage(void);
void Voltage_Display(void);
void Display_Lcd1602(void);
void Write_Time(void);
/*前景色*/
#define F_BLACK "\033[30m" /* 黑色 */
#define F_RED "\033[31m" /* 红色 */
#define F_GREEN "\033[32m" /* 绿色 */
#define F_YELLOW "\033[33m" /* 黄色 */
#define F_BLUE "\033[34m" /* 蓝色 */
#define F_MAGENTA "\033[35m" /* 紫色 */
#define F_CYAN "\033[36m" /* 青色 */
#define F_WHITE "\033[37m" /* 白色 */
#define F_LIGHTRED "\033[1;31m" /* 亮红 */
#define F_LIGHTGREEN "\033[1;32m" /* 亮绿 */
#define F_LIGHTYELLOW "\033[1;33m" /* 亮黄 */
#define F_LIGHITBLUE "\033[1;34m" /* 亮蓝 */
#define F_LIGHTMAGENTA "\033[1;35m" /* 亮紫 */
#define F_LIGHTCYAN "\033[1;36m" /* 亮青 */
#define F_LIGHTWHITE "\033[1;37m" /* 亮白 */
/*背景色*/
#define B_BLACK "\033[40m" /* 黑色 */
#define B_RED "\033[41m" /* 红色 */
#define B_GREEN "\033[42m" /* 绿色 */
#define B_YELLOW "\033[43m" /* 黄色 */
#define B_BLUE "\033[44m" /* 蓝色 */
#define B_MAGENTA "\033[45m" /* 紫色 */
#define B_CYAN "\033[46m" /* 青色 */
#define B_LIGHTRED "\033[41;1m" /* 亮红 */
#define B_LIGHTGREEN "\033[42;1m" /* 亮绿 */
#define B_LIGHTYELLOW "\033[43;1m" /* 亮黄 */
#define B_LIGHTBLUE "\033[44;1m" /* 亮蓝 */
#define B_LIGHTMAGENTA "\033[45;1m" /* 亮紫 */
#define B_LIGHTCYAN "\033[46;1m" /* 亮青 */
#define B_LIGHTWHITE "\033[47;1m" /* 亮白 */
#define BOLDFONT "\033[1m" /* Set blod font */
#define UNDERLINEFONT "\033[4m" /* Set underline font */
#define CLEARSCREEN "\033[2J" /* Clear screen */
#define CURSORHOME "\033[H" /* Restore cursor to home */
#define SAVECURSOR "\033[s" /* Save cursor position */
#define RESTORECURSOR "\033[u" /* Restore cursor to saved position */
#define SINGLEWIDTH "\033#5" /* Normal, single-width characters */
#define DOUBLEWIDTH "\033#6" /* Creates double-width characters */
#define FREEZETOP "\033[2;25r" /* Freeze top line */
#define FREEZEBOTTOM "\033[1;24r" /* Freeze bottom line */
#define UNFREEZE_TB "\033[r" /* Unfreeze top line and bottom line */
#define BLINKTEXT "\033[5m" /* Blink text */
#define REVERSEMODE "\033[7m" /* Set hyper terminal to reverse mode */
#define LIGHTREVERSEMODE "\033[1,7m" /* Set hyper terminal to light reverse mode */
#endif
terminal.c
#include"terminal.h" //包含头文件
#include"beep.h"
#include"ds18b20.h"
#include"led.h"
#include"dataled.h"
#include"delay.h"
#include"lcd1602.h"
#include"adc0804.h"
#include"ds1302.h"
//#include"at24c02.h"
#define TURE 1 //宏定义参数值
#define FALSE 0
uint temperature,voltage;
uchar input_size = 0;
uchar i,Taddr;
//***定义各类命令操作符
//uchar Operation[] = "wenqian";
uchar Operation_music[] = "music";
//uchar Operation_stop[] = "stop";
uchar Operation_temper[] = "temper";
uchar Operation_ledon[] = "ledon";
uchar Operation_ledoff[] = "ledoff";
uchar Operation_dataledon[] = "dataledon";
uchar Operation_dataledoff[] = "dataledoff";
uchar Operation_writetime[] = "writetime";
uchar Operation_compute[] = "compute";
uchar Operation_voltage[] = "voltage";
uchar Operation_clear[] = "clear";
uchar Operation_reboot[] = "reboot";
uchar Operation_help[] = "help";
uchar Operation_F_color[] = "bule";
//uchar Operation_B_color[] = "green";
uchar rec[20];
uchar code num_to_char[] = {"0123456789ABCDEF"}; /*定义数字跟ASCII码的关系*/
uchar temper[] = {"00.00\r\n"}; /*定义温度值ASCII码*/
uchar result[] = {"00000"}; /*定义计算值ASCII码*/
uchar vol[] = {"0.00"}; /*定义电压值ASCII码*/
/*终端修改时间操作命令*/
uchar data ds1302_time[] = {0x00,0x00,0x16,0x10,0x06,0x01,0x13};/*格式为: 秒 分 时 日 月 星期 年 */
uchar data lcd1602_line1[] = {"00/00/00 00.00℃"}; /*1602第一行显示数据初始化*/
uchar data lcd1602_line2[] = {"00:00:00 Monday"}; /*1602第二行显示数据初始化*/
uchar data time_buzzer[9];
/*
**************************************************************************************************
** 超级终端设置函数
**
** Init_Terminal() :超级终端设置初始化
** Send() : 发送函数设定,用来发送字符串
** Sendbyte() :发送单个字符
** Rec_Terminal() :接收函数设定,用来接收字符串
** Compare_Terminal() :比较函数设定,带返回值(TURE or FALSE)
** Clear_Terminal() :清除缓存函数,即清除接收数组中的数据
**
**************************************************************************************************
*/
void Init_Terminal(void)
{
WELA = 0; //关闭数码管锁存端
DULA = 0;
TMOD |= 0x21; //选择定时器1工作模式2,不影响定时器的其他设置
SCON = 0x50; //选择10位异步通信
PCON = 0x80; //波特率设置加倍
TH1 = 0xFF; //波特率为57600,fOSC=11.0592MHZ
TL1 = 0xFF;
// frq = 0x00; //蜂鸣器PWM调节
TH0 = 0x00; //定时器0中断初值
TL0 = 0xff;
TR0 = 0;
TR1 = 1;
RI = 0;
TI = 0;
Send(CLEARSCREEN);
Send(F_BLUE);
Wenqian();
Send(">> Please Operate \r\n\r\n");
Set1302(ds1302_time);
Init_Lcd1602();
IE = 0x92; //EA、ET0、ES =1;
// IP = 0X10; //串行口中断定义为高优先级中断
}
//***----send:发送函数设定,用来发送字符串
//***----输入用于发送的字符串或字符串地址
void Send(char *add)
{
while(*add != '\0')
{
SBUF = *add++; //发送字符串
while(!TI);
TI = 0;
}
}
///***发送单个字符
void Sendbyte(char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
//***----receive:接收函数设定
//***----接收字符串和存放字符串
void Rec_Terminal(char size)
{
uchar temp;
do
{
while(!RI);
RI = 0;
temp = SBUF;
if((temp == 0x08) && (input_size > 0)) //退格指令
{
input_size = input_size - 1;
Sendbyte(0x08);
Sendbyte(' ');
}
SBUF = temp;
while(!TI);
TI = 0;
if(temp != 0x08) //当输入退格键(0x08)时,数据不存入存储数组
{
rec[input_size] = temp;
input_size ++;
}
if(input_size >= size) //当接收数组存放的数目大于设定值时,跳出循环
break;
}
while(temp != '\r'); //当操作回车键时,不进入循环
}
//***----compare比较函数设定,带返回值(0 or 1)
//***----输入两个字符串的地址
uchar Compare_Terminal(char *i,char *j)
{
while(*i != '\0')
{
if(*i++ != *j++) //字符串逐个字符进行比较,若不相同,返回值为0
return FALSE;
}
if(*j != '\r') //没有操作回车键,返回值为0
return FALSE;
return TURE;
}
//***----clear清除缓存函数
void Clear_Terminal(char size)
{
char n;
for(n=0; n<=size; n++)
{
rec[n] = 0; //清零
}
input_size = 0; //清零
}
/*
**************************************************************************************************
** 终端信息显示函数
**
** 描述:显示文字内容,在该系统中,执行清屏操作后,会显示该信息内容
**
**************************************************************************************************
*/
void Display_Terminal(void)
{
Send("--------------------------今天心情不错--------------------------\r\n");
Send(" \r\n");
Send(" \r\n");
Send(" \r\n");
Send(" 人生自古谁无死,留取丹心照汗青 \r\n");
Send(" \r\n");
Send(" \r\n\r\n");
}
/*
**************************************************************************************************
** 功能函数
**
** 功能:为终端提供相应操作函数,键入以下对应命令行,即可实现相应的操作
**
** help : 获得该控制系统的所有命令行提示
** wenqian :获得该系统额外信息
** reboot :软件复位MCU
** clear :清除当前屏幕内容
**
**************************************************************************************************
*/
void Help(void)
{
Send(">> help -- Command help \r\n>> dataledon/dataledoff -- Operate dataled on/off \r\n");
Send(">> ledon/ledoff -- Operate led on/off \r\n>> temper -- Read temperature \r\n");
Send(">> sos -- Operate buzzer speak \r\n>> music -- Buzzer sing music \r\n");
Send(">> voltage -- Display voltage \r\n>> writetime -- Change time \r\n");
Send(">> clear -- Clear screen \r\n>> reboot -- Reboot the MCU \r\n\r\n");
// Send(">> wenqian -- Welcome \r\n\r\n");
}
****欢迎函数*****//
void Wenqian(void)
{
Send("-->> wenqian -- welcome ! \r\n");
Send("-->> hello world -- \r\n");
// Display_Terminal();
}
///****复位函数*****
void Reboot(void)
{
(*(void(*)())0)(); //调用保存在首地址为0 的一段区域内的函数
Send("\r\n\r\n"); //即MCU复位
}
///****清屏函数******
void Clear(void)
{
Send(CLEARSCREEN); //清除屏幕
Display_Terminal(); //显示
}
/*
**************************************************************************************************
** 1602显示函数
**
** 功能:将从DS1302读取的时间数据显示在LCD1602上
**
**************************************************************************************************
*/
void Display_Lcd1602(void)
{
Terminal_Temper();
//***闹钟状态扫描
Buzzer_Timer();
//***ds1302读取当前时间
Get1302(ds1302_time);
//***lcd1602显示数据读取***//
//-----第一行数据读取----//
lcd1602_line1[0] = num_to_char[ds1302_time[6] / 16];
lcd1602_line1[1] = num_to_char[ds1302_time[6] % 16]; //年
lcd1602_line1[3] = num_to_char[ds1302_time[4] / 16];
lcd1602_line1[4] = num_to_char[ds1302_time[4] % 16]; //月
lcd1602_line1[6] = num_to_char[ds1302_time[3] / 16];
lcd1602_line1[7] = num_to_char[ds1302_time[3] % 16]; //日
lcd1602_line1[10] = num_to_char[temperature / 1000];
lcd1602_line1[11] = num_to_char[temperature / 100 % 10];
lcd1602_line1[13] = num_to_char[temperature / 10 % 10];
lcd1602_line1[14] = num_to_char[temperature % 10]; //温度
//-----第二行数据读取----//
lcd1602_line2[0] = num_to_char[ds1302_time[2] / 16];
lcd1602_line2[1] = num_to_char[ds1302_time[2] % 16]; //时
lcd1602_line2[3] = num_to_char[ds1302_time[1] / 16];
lcd1602_line2[4] = num_to_char[ds1302_time[1] % 16]; //分
lcd1602_line2[6] = num_to_char[ds1302_time[0] / 16];
lcd1602_line2[7] = num_to_char[ds1302_time[0] % 16]; //秒
///----1602显示数据
for(i=0; i<16; i++)
{
Write_Com_Lcd1602(0x80 + i);
Write_Dat_Lcd1602(lcd1602_line1[i]);
}
for(i=0; i<16; i++)
{
Write_Com_Lcd1602(0x80 + 0x40 + i);
Write_Dat_Lcd1602(lcd1602_line2[i]);
}
}
/*
**************************************************************************************************
** LCD1602终端修改时间函数
**
** 功能:输入命令 writetime ;进入修改时间参数操作
** 输入格式为 11(年)08(月)05(日)10(时)12(分) 只输入数字(十位)
**
**************************************************************************************************
*/
void Write_Time(void)
{
uchar temp,i;
Send(">> Please input current time \r\n");
Send(">> 输入格式:年月日时分秒(闹钟)时(闹钟)分 \r\n");
//由于此前存储数组中已存放有数据,所以需要对存储数组进行清除
Clear_Terminal(input_size); //清除缓存区
//***判断输入数据是否有效
do
{
while(!RI);
RI = 0;
temp = SBUF;
if((temp == 0x08) && (input_size > 0)) //退格指令
{
input_size = input_size - 1;
Sendbyte(0x08);
Sendbyte(' ');
}
SBUF = temp;
while(!TI);
TI = 0;
if(temp != 0x08) //当输入退格键(0x08)时,数据不存入存储数组
{
rec[input_size] = temp; //存放输入的时间信息
input_size ++;
}
if(input_size > 25) //当接收数组存放的数目大于设定值时,跳出循环
break;
}
while((temp != '\r') /*&& (temp >= '0') && (temp <= '9')*/); //当操作回车键、输入非数字时,不进入循环
// Send("\r\n>> Error : It is a invalid number and break \r\n\r\n");
Send("\r\n\r\n");
//时间修改
//格式:11 08 08 10 12 30
//2位十进制转换为BCD码并存入数组
ds1302_time[6] = ((rec[0] << 4) & 0xf0) + (rec[1] & 0x0f); //年
ds1302_time[4] = ((rec[2] << 4) & 0xf0) + (rec[3] & 0x0f); //月
ds1302_time[3] = ((rec[4] << 4) & 0xf0) + (rec[5] & 0x0f); //日
ds1302_time[2] = ((rec[6] << 4) & 0xf0) + (rec[7] & 0x0f); //时
ds1302_time[1] = ((rec[8] << 4) & 0xf0) + (rec[9] & 0x0f); //分
ds1302_time[0] = ((rec[10] << 4) & 0xf0) + (rec[11] & 0x0f); //秒
time_buzzer[7] = ((rec[12] << 4) & 0xf0) + (rec[13] & 0x0f); //闹钟——时
time_buzzer[8] = ((rec[14] << 4) & 0xf0) + (rec[15] & 0x0f); //闹钟——分
Set1302(ds1302_time);
lcd1602_line1[0] = rec[0];
lcd1602_line1[1] = rec[1]; //修改 年
lcd1602_line1[3] = rec[2];
lcd1602_line1[4] = rec[3]; //月
lcd1602_line1[6] = rec[4];
lcd1602_line1[7] = rec[5]; //日
lcd1602_line2[0] = rec[6];
lcd1602_line2[1] = rec[7]; //时
lcd1602_line2[3] = rec[8];
lcd1602_line2[4] = rec[9]; //分
lcd1602_line2[6] = rec[10];
lcd1602_line2[7] = rec[11]; //秒
lcd1602_line2[10] = rec[12];
lcd1602_line2[11] = rec[13];
lcd1602_line2[13] = rec[14];
lcd1602_line2[14] = rec[15]; //闹钟状态设置
Get1302(ds1302_time);
//***lcd1602显示数据读取***//
//-----第一行数据读取----//
lcd1602_line1[0] = num_to_char[ds1302_time[6] / 16];
lcd1602_line1[1] = num_to_char[ds1302_time[6] % 16]; //年
lcd1602_line1[3] = num_to_char[ds1302_time[4] / 16];
lcd1602_line1[4] = num_to_char[ds1302_time[4] % 16]; //月
lcd1602_line1[6] = num_to_char[ds1302_time[3] / 16];
lcd1602_line1[7] = num_to_char[ds1302_time[3] % 16]; //日
//-----第二行数据读取----//
lcd1602_line2[0] = num_to_char[ds1302_time[2] / 16];
lcd1602_line2[1] = num_to_char[ds1302_time[2] % 16]; //时
lcd1602_line2[3] = num_to_char[ds1302_time[1] / 16];
lcd1602_line2[4] = num_to_char[ds1302_time[1] % 16]; //分
lcd1602_line2[6] = num_to_char[ds1302_time[0] / 16];
lcd1602_line2[7] = num_to_char[ds1302_time[0] % 16]; //秒
///----1602显示修改后的数据
for(i=0; i<16; i++)
{
Write_Com_Lcd1602(0x80+i);
Write_Dat_Lcd1602(lcd1602_line1[i]);
}
for(i=0; i<16; i++)
{
Write_Com_Lcd1602(0x80 + 0x40 + i);
Write_Dat_Lcd1602(lcd1602_line2[i]);
}
}
/*
**************************************************************************************************
** 蜂鸣器操作函数
**
** 功能:利用蜂鸣器实现不同的声音信号产生,并代表响应操作状态
**
** 包括蜂鸣器音乐播放器,蜂鸣器闹钟提醒和蜂鸣器整点报时
**
** 闹钟蜂鸣器提醒,按键 S5 停止
**
**************************************************************************************************
*/
//*****蜂鸣器闹钟,整点报时****//
void Buzzer_Timer(void)
{
Taddr = 0x81;
for(i=0; i<7; i++) //读取DS1302实时时间
{
time_buzzer[i] = R1302(Taddr);
Taddr += 2;
}
if((time_buzzer[1] == time_buzzer[8]) && (time_buzzer[2] == time_buzzer[7]))
{
Buzzer_Time();
if(KEY == 0) //按键停止闹钟
{
Delay_ms(5); //按键延时消抖
if(KEY == 0)
{
time_buzzer[7] = '0'; //这里保证在任何时候不响应闹钟
time_buzzer[8] = '0';
}
}
}
else if((time_buzzer[0] == 0x00) && (time_buzzer[1] == 0x00)) //整点报时
{
FM = 0;
Delay_ms(500);
FM = 1;
}
else //其余情况,蜂鸣器停止鸣叫
FM = 1;
}
///***蜂鸣器闹钟提醒****
void Buzzer_Time(void)
{
FM = 0;
Delay_ms(500);
FM = 1;
Delay_ms(500);
}
///*****蜂鸣器播放音乐****///
void Buzzer_Music(void)
{
Send(">> Please appreciate the music \r\n\r\n");
Beep_Music(); //蜂鸣器播放音乐
}
/*void timer0() interrupt 1 using 1
{
TH0 = 0xfe;
TL0 = frq;
FM = ~ FM;
}
///****蜂鸣器报警求助信号**** /
void Buzzer_Sos(void)
{
uint count = 5000;
TR0 = 1;
while(count--)
{
frq++;
Delay_ms(1);
}
TR0 = 0;
FM = 1;
Send(">> SOS ? you should call 911 \r\n\r\n");
} */
/*
**************************************************************************************************
** 电压显示函数
**
** 功能:将ADC0804读取的电压值值转换为ASCII码存入vol数组,
** 通过超级终端显示出来
**
** Terminal_Voltage():将DS18B20读取的环境温度值转换为ASCII码并存入temper数组中
** Voltage_Display() :将temper数组中的温度值发送至超级终端
**
**************************************************************************************************
*/
void Terminal_Voltage(void)
{
voltage = Adc0804();
vol[0] = num_to_char[voltage /100];
vol[2] = num_to_char[voltage /10 %10];
vol[3] = num_to_char[voltage %10];
}
void Voltage_Display(void)
{
uchar i = 0;
Terminal_Voltage();
Send(">> 当前测点电压值为:");
while(temper[i] != '\0')
{
SBUF = vol[i++]; //发送电压值
while(!TI);
TI = 0;
if(i == 4)
Send("V");
}
Send("\r\n\r\n");
}
/*
**************************************************************************************************
** 温度显示函数
**
** 功能:将传感器读取的温度值转换为ASCII码存入temper数组,
** 通过超级终端显示出来
**
** Terminal_Temper():将DS18B20读取的环境温度值转换为ASCII码并存入temper数组中
** Temper_Display() :将temper数组中的温度值发送至超级终端
**
**************************************************************************************************
*/
void Terminal_Temper(void)
{
temperature = Ds18b20();
temper[0] = num_to_char[temperature / 1000];
temper[1] = num_to_char[temperature / 100 % 10];
temper[3] = num_to_char[temperature / 10 % 10];
temper[4] = num_to_char[temperature % 10];
}
void Temper_Display(void)
{
uchar i = 0;
Terminal_Temper();
Send(">> 当前环境温度值为:");
while(temper[i] != '\0')
{
SBUF = temper[i++]; //发送温度值
while(!TI);
TI = 0;
if(i == 5)
Send("℃");
}
Send(" \r\n");
}
/*
**************************************************************************************************
** 数码管显示和关闭
**
** 功能:进入操作后,可以连续输入任意数字,然后终端上显示,
** 当输入非数字字符时,系统提示警告并退出当前环境,之后可操作数码管关闭。
**
**************************************************************************************************
*/
void Dataled_On(void)
{
uchar temp, i = 0;
Dataled_Display(10);
Send(">> Lighton the dataled and you can make the dataled display the number you want\r\n");
Send(">> Please input number \r\n>> ");
while(!RI);
RI = 0;
temp = SBUF;
/****输入为数字才控制数码管显示,否则将退出当前服务程序****/
while((temp >= '0') && (temp <= '9'))
{
Send(" ");
Sendbyte(temp);
i++;
Dataled_Display(temp - 0x30); //控制显示相应输入数字
while(!RI);
RI = 0;
temp = SBUF;
if(i == 10)
{
Send("\r\n>> ");
i=0;
}
}
Send("\r\n>> ");
Sendbyte(temp);
Send("\r\n>> Error : It is a invalid number and break \r\n\r\n"); //发送错误报告并退出当前服务
}
///****数码管关闭****
void Dataled_Off(void)
{
Send(">> Lightoff the DATALED \r\n\r\n");
Dataled_Display(11);
}
/*
**************************************************************************************************
** LED显示和关闭
**
** 通过命令 ledon 和 ledoff 控制led的显示和关闭
** 并附带操作成功提示功能
**
**************************************************************************************************
*/
void Led_On(void)
{
Send(">> Lighton the LED \r\n\r\n");
Led_Lighton();
}
*****关闭LED***///
void Led_Off(void)
{
Send(">> Lightoff the LED \r\n\r\n");
Led_Lightoff();
}
/*
**************************************************************************************************
** 实时计算函数
**
** 功能:输入操作命令 compute ,则进入相应操作内容
** 随即输入计算操作数据,该系统只可进行输入数据为10以内的计算。
**
**------备注:该函数一开始是在另一程序中进行测试,并成功获得预期结果。
** 但移植入本程序中没有得到预期结果,故为待检测函数。
**
**
**************************************************************************************************
*/
void Compute_Terminal(void)
{
uint a,b,out,i;
Clear_Terminal(input_size); //清除缓存区
Rec_Terminal(20);
a = rec[0] - 0x30;
b = rec[2] - 0x30;
switch(rec[1])
{
case '+': out = a + b; break;
case '-': out = a - b; break;
case '*': out = a * b; break;
case '/': out = a / b; break;
}
Send("\r\n>> ");
result[0] = num_to_char[out / 10000];
result[1] = num_to_char[out / 1000 % 10];
result[2] = num_to_char[out / 100 % 10];
result[3] = num_to_char[out / 10 % 10];
result[4] = num_to_char[out % 10];
while(result[i] != '\0')
{
SBUF = result[i++];
while(!TI);
TI = 0;
}
Send(" \r\n\r\n");
}
/*
**************************************************************************************************
** 终端控制函数
**
** 功能:输入相应操作命令,则进入相应操作内容
** 当输入非正确操作命令时,系统提示警告并退出当前环境
**
**************************************************************************************************
*/
void Terminal(void)
{
Display_Lcd1602();
}
/*
**************************************************************************************************
** 串行口中断函数
**
** 功能:超级终端输入数据时,响应中断,并执行相应指令操作
**
**************************************************************************************************
*/
void Serialinterrupt(void) interrupt 4
{
Rec_Terminal(20);
Send("\r\n");
if((Compare_Terminal(Operation_help,rec) == FALSE) && (input_size >= 20))
{
Send(">> Warnning : Your command string is too long! \r\n\r\n"); //输入命令串过长警告
}
else if(Compare_Terminal(Operation_F_color,rec) == TURE)
{
Send(F_BLUE); //设置显示颜色,可选及扩展操作
}
else if(Compare_Terminal(Operation_help,rec) == TURE)
{
Help(); //命令帮助
}
else if(Compare_Terminal(Operation_reboot,rec) == TURE)
{
Reboot(); //重新启动MCU
}
else if(Compare_Terminal(Operation_clear,rec) == TURE)
{
Clear(); //清屏
}
else if(Compare_Terminal(Operation_music,rec) == TURE) //蜂鸣器播放音乐
{
Buzzer_Music();
}
/* else if(Compare_Terminal(Operation_stop,rec) == TURE) //闹钟停止
{
time_buzzer[7] = 0;
time_buzzer[8] = 0;
} */
else if(Compare_Terminal(Operation_writetime,rec) == TURE) //进入时间修改操作
{
Write_Time();
}
else if(Compare_Terminal(Operation_voltage,rec) == TURE) //显示电压值
{
Voltage_Display();
}
else if(Compare_Terminal(Operation_temper,rec) == TURE) //显示温度值
{
Temper_Display();
}
else if(Compare_Terminal(Operation_compute,rec) == TURE) //启动简易计算器
{
Compute_Terminal();
}
else if(Compare_Terminal(Operation_ledon,rec) == TURE) //点亮led
{
Led_On();
}
else if(Compare_Terminal(Operation_ledoff,rec) == TURE) //关灭led
{
Led_Off();
}
else if(Compare_Terminal(Operation_dataledon,rec) == TURE) //数码管全显
{
Dataled_On();
}
else if(Compare_Terminal(Operation_dataledoff,rec) == TURE) //数码管全灭
{
Dataled_Off();
}
else
Send(">> Error : It is a invalid command \r\n>> If you want to konw available commands, type 'help' \r\n\r\n"); //发送错误报告
Clear_Terminal(input_size); //清除缓存区
}
adc0804.c
#include"adc0804.h"
#include"delay.h"
sbit WELA = P2^7;
sbit AD_WR = P3^6;
sbit AD_RD = P3^7;
uchar adv;
uint value;
/*
**************************************************************************************************
** ADC0804转换函数
**
** 描述:ADC0804为8位并行芯片,可一次性读取AD转换后电压值,
** adc0804()无参带返回整型电压值
**
**************************************************************************************************
*/
uint Adc0804(void)
{
WELA = 1;
P0 &= 0x7f; //置ad_cs端为0.选通ad,且不影响P0口的其他作用
// WELA = 0;
AD_WR = 0;
_nop_();
AD_WR = 1;
P0 |= 0x80; //关闭ad_cs
Delay_ms(5);
P0 &= 0x7f;
AD_RD = 0;
adv = P1;
AD_RD = 1;
P0 |= 0x80; //关闭ad_cs
WELA = 0;
value = (uint)(adv*100*5.0/255); //转换公式
AD_WR = 0; //该引脚与LCD的读写选择端为同一引脚,此处将其置零,不影响LCD的读写显示
return value;
}
at24c02.c
#include"at24c02.h"
#include"delay.h"
sbit SDA = P2^0;
sbit SCL = P2^1; //申明数据线和时钟线端口
//***初始化
void Init_IIc(void)
{
SCL = 1;
SDA = 1;
}
//***开始信号
void Start_IIc(void)
{
SCL = 1;
SDA = 1;
delay5us;
SDA = 0;
}
//***停止信号
void Stop_IIc(void)
{
SCL = 1;
SDA = 0;
delay5us;
SDA = 1;
}
//***应答信号
void Respons_IIc(void)
{
uchar i = 0;
SCL = 1;
delay5us;
while((SDA == 1) && (i < 255))
i++;
}
//***非应答信号
void Norespons_IIc(void)
{
SCL = 1;
SDA = 1;
delay5us;
}
//***写一个字节函数
void Write_Byte_IIc(uchar dat)
{
uchar i;
SCL = 0;
for(i=0; i<8; i++)
{
if(dat & 0x80)
SDA = 1;
else
SDA = 0;
dat = dat << 1;
delay5us;
SCL = 1;
delay5us;
SCL = 0;
}
}
//***读一个字节函数
uchar Read_Byte_IIc(void)
{
uchar temp,i;
for(i=0; i<8; i++)
{
SCL = 1;
temp = temp << 1;
if(SDA)
temp = temp | 0x01;
else
temp = temp | 0x00;
delay5us;
SCL = 0;
}
return temp;
}
//***写操作函数
void Write_IIc(uchar add,uchar dat)
{
Start_IIc();
Write_Byte_IIc(0xa0);
Respons_IIc();
Write_Byte_IIc(add);
Respons_IIc();
Write_Byte_IIc(dat);
Respons_IIc();
Stop_IIc();
}
//***读操作函数
uchar Read_IIc(uchar add)
{
uchar value;
Start_IIc();
Write_Byte_IIc(0xa0);
Respons_IIc();
Write_Byte_IIc(add);
Respons_IIc();
Start_IIc();
Write_Byte_IIc(0xa1);
Respons_IIc();
value = Read_Byte_IIc();
Norespons_IIc();
Stop_IIc();
return value;
}
ds18b20.c
#include"delay.h"
#include"ds18b20.h"
sbit DQ = P2^2;
uint count;
/*
**************************************************************************************************
** DS18B20操作函数
**
** 功能:单总线操作命令格式,读取当前环境温度值
**
** start_ds18b20() :DS18B20单总线开始函数,
** write_byte_ds18b20():DS18B20单总线写字节函数,低位写入
** read_byte_ds18b20() :DS18B20单总线读字节函数
** ds18b20() :DS18B20单总线温度读取,转换,返回值为 当前温度值 * 100
**
**************************************************************************************************
*/
void Start_Ds18b20(void)
{
DQ = 1;
DQ = 0;
delay480us;
DQ = 1;
delay60us;
while(DQ == 1);
delay240us;
DQ = 1;
delay240us;
}
void Write_Byte_Ds18b20(uchar dat)
{
uchar i;
for(i=0; i<8; i++)
{
DQ=1;
DQ=0;
delay2us;
if(dat & 0x01)
DQ = 1;
else
DQ = 0;
dat = dat >> 1;
delay60us;
DQ = 1;
delay2us;
}
}
uchar Read_Byte_Ds18b20(void)
{
uchar i,temp;
for(i=0; i<8; i++)
{
DQ = 1;
DQ = 0;
delay2us;
DQ = 1;
temp = temp >> 1;
if(DQ == 1)
temp = temp | 0x80;
else
temp = temp | 0x00;
delay60us;
DQ = 1;
delay2us;
}
return temp;
}
uint Ds18b20(void)
{
uchar a,b;
float temper;
uint temp;
Start_Ds18b20();
Write_Byte_Ds18b20(0xcc);
Write_Byte_Ds18b20(0x44);
Start_Ds18b20();
Write_Byte_Ds18b20(0xcc);
Write_Byte_Ds18b20(0xbe);
//***温度读取
a = Read_Byte_Ds18b20();
b = Read_Byte_Ds18b20();
//***温度转换
temp = b;
temp = (temp << 8) | a;
temper = temp * 0.0625;
count = temper * 100 + 0.5;
return count;
}
ds1302.c
#include"ds1302.h"
/*sbit SCLK = P3^2;
sbit RST = P3^3;
sbit IO = P2^4;
/*
**************************************************************************************************
** DS1302写函数
**
** 描述:DS1302写操作,包含写入单个字节和写入操作
**
** Write_Ds1302_Byte(uchar temp) :写入单个字节;
** Write_Ds1302(uchar add,uchar dat):写操作
**
**************************************************************************************************
*
void Write_Ds1302_Byte(uchar temp)
{
uchar i;
RST = 1;
for(i=0; i<8; i++)
{
SCLK = 0;
IO = temp & 0x01;
temp >>= 1;
SCLK = 1; //上升沿写入
}
}
void Write_Ds1302(uchar add,uchar dat)
{
RST = 0;
SCLK = 0;
RST = 1;
Write_Ds1302_Byte(add);
Write_Ds1302_Byte(dat);
SCLK = 1;
RST = 0;
IO = 0;
}
/*
**************************************************************************************************
** DS1302读函数
**
** 描述:DS1302读操作,包含读出单个字节和读出操作
**
** Read_Ds1302_Byte(void) :读出单个字节,带返回值;
** uchar Read_Ds1302(uchar add):读操作,带返回值
**
**************************************************************************************************
*
uchar Read_Ds1302_Byte(void)
{
uchar i,temp;
RST = 1;
for(i=0; i<8; i++)
{
SCLK = 1;
temp >>= 1;
if(IO)
temp |= 0x80;
SCLK = 0; //下降沿数据读取
}
return temp;
}
uchar Read_Ds1302(uchar add)
{
uchar temp;
RST = 0;
SCLK = 0;
RST = 1;
Write_Ds1302_Byte(add);
temp = Read_Ds1302_Byte();
SCLK = 1;
RST = 0;
IO = 0;
return temp;
}
/*
**************************************************************************************************
** DS1302时间数据初始化和读取
**
** 描述:DS1302初始化时间以及读取时间数据
**
** Ds1302_Set(uchar *clock):设置初始时间数据
** Ds1302_Get(uchar time[]):读取芯片当前运转时间
**
**************************************************************************************************
*
void Ds1302_Set(uchar *clock)
{
uchar i;
uchar add = 0x80;
for(i=0; i<7; i++)
{
Write_Ds1302(add,*clock); /*格式为: 秒 分 时 日 月 星期 年 *
clock++;
add +=2;
}
}
void Ds1302_Get(uchar time[])
{
uchar i;
uchar add = 0x81;
for (i=0; i<7; i++)
{
time[i] = Read_Ds1302(add); /*格式为: 秒 分 时 日 月 星期 年 *
add += 2;
}
} */
/*sbit SCLK = P3^2;
sbit RST = P3^3;
sbit IO = P2^4;
/*
**************************************************************************************************
** DS1302写函数
**
** 描述:DS1302写操作,包含写入单个字节和写入操作
**
** Write_Ds1302_Byte(uchar temp) :写入单个字节;
** Write_Ds1302(uchar add,uchar dat):写操作
**
**************************************************************************************************
*
void Write_Ds1302_Byte(uchar temp)
{
uchar i;
RST = 1;
for(i=0; i<8; i++)
{
SCLK = 0;
IO = temp & 0x01;
temp >>= 1;
SCLK = 1; //上升沿写入
}
}
void Write_Ds1302(uchar add,uchar dat)
{
RST = 0;
SCLK = 0;
RST = 1;
Write_Ds1302_Byte(add);
Write_Ds1302_Byte(dat);
SCLK = 1;
RST = 0;
IO = 0;
}
/*
**************************************************************************************************
** DS1302读函数
**
** 描述:DS1302读操作,包含读出单个字节和读出操作
**
** Read_Ds1302_Byte(void) :读出单个字节,带返回值;
** uchar Read_Ds1302(uchar add):读操作,带返回值
**
**************************************************************************************************
*
uchar Read_Ds1302_Byte(void)
{
uchar i,temp;
RST = 1;
for(i=0; i<8; i++)
{
SCLK = 1;
temp >>= 1;
if(IO)
temp |= 0x80;
SCLK = 0; //下降沿数据读取
}
return temp;
}
uchar Read_Ds1302(uchar add)
{
uchar temp;
RST = 0;
SCLK = 0;
RST = 1;
Write_Ds1302_Byte(add);
temp = Read_Ds1302_Byte();
SCLK = 1;
RST = 0;
IO = 0;
return temp;
}
/*
**************************************************************************************************
** DS1302时间数据初始化和读取
**
** 描述:DS1302初始化时间以及读取时间数据
**
** Ds1302_Set(uchar *clock):设置初始时间数据
** Ds1302_Get(uchar time[]):读取芯片当前运转时间
**
**************************************************************************************************
*
void Ds1302_Set(uchar *clock)
{
uchar i;
uchar add = 0x80;
for(i=0; i<7; i++)
{
Write_Ds1302(add,*clock); /*格式为: 秒 分 时 日 月 星期 年 *
clock++;
add +=2;
}
}
void Ds1302_Get(uchar time[])
{
uchar i;
uchar add = 0x81;
for (i=0; i<7; i++)
{
time[i] = Read_Ds1302(add); /*格式为: 秒 分 时 日 月 星期 年 *
add += 2;
}
} */
sbit T_CLK = P3^2; /*实时时钟时钟线引脚 */
sbit T_IO = P2^4; /*实时时钟数据线引脚 */
sbit T_RST = P3^3; /*实时时钟复位线引脚 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:wenqian 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar i;
uchar ucAddr = 0x80;
EA = 0;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
for(i =7; i>0; i--)
{
W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
EA = 1;
}
/********************************************************************
函 数 名:Get1302()
功 能:读取DS1302当前时间
说 明:
调 用:R1302()
入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
EA = 0;
for (i=0; i<7; i++)
{
ucCurtime[i] = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
ucAddr += 2;
}
EA = 1;
}
lcd1602.c
#include"lcd1602.h"
//***写指令函数
void Write_Com_Lcd1602(uchar com)
{
lcdrs = 0; //选择写命令模式
P0 = com; //将要写入的命令字送到数据总线上
Delay_ms(5); //延时,是数据稳定
lcden = 1; //使能端-高脉冲,发送数据
Delay_ms(5);
lcden = 0;
}
//***写数据函数
void Write_Dat_Lcd1602(uchar dat)
{
lcdrs = 1; //选择写数据模式
P0 = dat; //将要写入的数据送到数据总线上
Delay_ms(5);
lcden = 1;
Delay_ms(5);
lcden = 0;
}
//***初始化函数
void Init_Lcd1602(void)
{
lcden = 0; //拉低使能端
lcdrw = 0; //选择写模式
Write_Com_Lcd1602(0x38); //设置16*2显示,5*7点阵,8位数据端口
Write_Com_Lcd1602(0x0c); //设置开显示,不显示光标
Write_Com_Lcd1602(0x06); //写一个字符后地址指针加1
Write_Com_Lcd1602(0x01); //显示清零,数据指针清零
}
led.c
#include"led.h"
#define led P1
#define on 0x00
#define off 0xff
sbit DIOLA = P2^5; //锁存端
/*
**************************************************************************************************
** LED显示函数
**
** 功能:LED的显示和关闭
**
**************************************************************************************************
*/
//***点亮led
void Led_Lighton(void)
{
DIOLA = 1;
led = on;
DIOLA = 0;
}
//***关灭led
void Led_Lightoff(void)
{
DIOLA = 1;
led = off;
DIOLA = 0;
}
beep.c
#include"delay.h"
#include"beep.h"
uchar code SOUNDLONG[]; //声明音长表
uchar code SOUNDTONE[]; //声明音调表
/*
**************************************************************************************************
** 蜂鸣器操作函数
**
** 功能:蜂鸣器两种不同的鸣叫方式
**
** beep_music():蜂鸣器演奏《生日快乐》
** Music() :通过改变蜂鸣器的占空比来实现音调和音量调节
** beep_warn() :蜂鸣器简单的连续5次鸣叫
**
**************************************************************************************************
*/
void Beep_Music(void)
{
Music(); //演奏《生日快乐》
// delay_ms(2000);
/* delay_ms(2000); //演奏完毕延时
Music(2); //演奏《三轮车》
delay_ms(2000);
delay_ms(2000); //演奏完毕延时 */
}
void Music(void)
{
uint k,n; //定义循环辅助变量
uint SoundLong,SoundTone; //定义音长音调变量,音长指时间长度,音调指震荡频率
uint i,j,m; //定义循环辅助变量
do
{
if(i >= 57) //如果演奏超过定义部分则回到初始位置
i = 0;
if(j >= 57)
j = 0;
SoundLong = SOUNDLONG[i]; //从表中取得音长
SoundTone = SOUNDTONE[j]; //从表中取得音调
i++; //指向下一个音长
j++; //指向下一个音调
for(n=0; n<SoundLong; n++) //音长指的是频率,这里决定蜂鸣器震动多少次
{
for(k=0; k<12; k++) //这里是震动一次
{
FM = 0; //打开
for(m=0; m<SoundTone/2; m++) //延时
;
FM = 1; //关闭
for(m=0; m<SoundTone/2; m++)
; //延时
}
}
Delay50us(11); //延时
}
while((SOUNDLONG[i] != 0) || (SOUNDTONE[j] != 0));//当两个表没有到达结尾时循环执行以上部分
}
uchar code SOUNDLONG[]=
{
9,3,12,12,12,24,
9,3,12,12,12,24,
9,3,12,12,12,12,12,
9,3,12,12,12,24,
0, //生日快乐end
9,3,12,12,12,24,
9,3,12,12,12,24,
9,3,12,12,12,12,12,
9,3,12,12,12,24,
0, //生日快乐end
};
uchar code SOUNDTONE[]=
{
212,212,190,212,159,169,
212,212,190,212,142,159,
212,212,106,126,159,169,190,
119,119,126,159,142,159,
0, //生日快乐end
212,212,190,212,159,169,
212,212,190,212,142,159,
212,212,106,126,159,169,190,
119,119,126,159,142,159,
0, //生日快乐end
};
dataled.c
#include"dataled.h"
#define dataled P0
//uchar code table_dataled[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x00,0xff};
//***共阳极数码管 0~9 10全亮,11全灭
uchar code table_dataled[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff,0x00};
//***共阴极数码管 0~9
/*
**************************************************************************************************
** 数码管函数
**
** 功能:改变数码管的段选端数据(位选端不变)使6位数码管连体显示数字
**
**************************************************************************************************
*/
void Dataled_Display(uchar num)
{
WELA = 1; //锁存器端口
dataled = table_dataled[num];
WELA = 0;
DULA = 1; //锁存器端口
dataled |= 0xc0;
DULA = 0;
}
#include"common.h"
#include"delay.h"
/*
**************************************************************************************************
** 延时函数
**
** 功能描述:fOSC = 11.0592MHZ ,分别延时 t ms 和 time us。
**
**************************************************************************************************
*/
void Delay_ms(uint t)
{
uchar j;
for(; t>0; t--)
for(j=110; j>0; j--);
}
void Delay50us(uchar time)
{
uchar a,b;
for(a=0; a<time; a++)
for(b=0; b<6; b++);
}
其中一部分 .h 头文件没有贴出来,里面是函数声明,以及一些芯片引脚的宏定义。
硬件开发算驱动开发吧,和芯片打交道的,需要阅读各个芯片资料(datasheet),必须根据芯片的时序图来编程,弄清楚芯片的最大延时是多少,抗电压值,以及时序图等,然后通过主控制器(MCU,CPU等)来驱动控制。