前言:针对串口的练手,此处只作代码记录,不进行分析和展示
目录
- 题目
- 代码
- 底层驱动
- 主程序核心代码
题目
代码
注:EEPROM的五组后丢弃用一个记录次数的变量进行循环即可,我没有写这一部分代码。
底层驱动
IIC
unsigned char rb2(){
unsigned char ret;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x03);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
//Delay(1);
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return ret;
}
unsigned char guangmin(){
unsigned char ret;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x01);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
//Delay(1);
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return ret;
}
void eepromwrite(unsigned char addr,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
这里有一点需要额外注意的是同时读取光敏和划变需要有额外的伪写操作。
主程序核心代码
#include <STC15F2K60S2.H>
#include "stdio.h"
#include "inithc138.h"
#include "delay.h"
#include "onewire.h"
#include "iic.h"
#include "ds1302.h"
#define de 5
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e, //F
0xbf
};
unsigned char show = 0;//显示功能切换
unsigned int temp = 0;//温度
bit ce = 1;
unsigned char voltage = 0;//读取rb2电压
unsigned int shidu = 0;//湿度
unsigned char ds1302writeaddr[3] = {0x80,0x82,0x84};
unsigned char ds1302readaddr[3] = {0x81,0x83,0x85};
unsigned char rtctime[3] = {0x55,0x59,0x23};
unsigned char light = 0;//光敏
unsigned char jiejin = 0;//接近为1,无事为0
bit workmode = 0;//0为自动传输模式,1为自动记录模式
unsigned long count = 0;//停留时间
unsigned char command[10];
unsigned char index = 0;
unsigned char uartcount = 0;
bit uartflag = 0;//1代表开始接受命令
bit uartflag2 = 0;//1代表开始识别命令
unsigned char ledstat = 0xff;
unsigned long tingliu = 0;
bit flag = 0;//停留时间记录以防清零
bit flag2 = 0;//防止重复记录时间
unsigned char jiejinshijian[3];
//************************************测温测湿度
void cewen(){
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
if(ce){
ce = 0;
Delay(200);
Delay(200);
Delay(120);
}
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = ((MSB << 8) | LSB) * 0.0625;
}
void ceshidu(){
voltage = rb2();
shidu = voltage * 99.00 / 255.00;
}
//************************************
//************************************DS1302实时时钟
void ds1302config(){
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i = 0;i < 3;i++){
Write_Ds1302_Byte(ds1302writeaddr[i],rtctime[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void ds1302read(){
unsigned char i;
for(i = 0;i < 3;i++){
rtctime[i] = Read_Ds1302_Byte(ds1302readaddr[i]);
}
}
//************************************
//************************************接近事件
void jieshijian(){
if(light <= 10){
jiejin = 1;
if(flag2 == 0){
flag2 = 1;
jiejinshijian[0] = rtctime[0];
jiejinshijian[1] = rtctime[1];
jiejinshijian[2] = rtctime[2];
}
}else{
flag2 = 0;
jiejin = 0;
}
}
//************************************
//************************************定时器0
void Timer0_Isr(void) interrupt 1
{
if(jiejin){
count++;//接近时间
}
if(uartflag){
uartcount++;
}
if(uartcount == 50){
uartflag = 0;
uartflag2 = 1;
}
}
void Timer0_Init(void) //5毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xA0; //设置定时初始值
TH0 = 0x15; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//************************************
//************************************串口通讯
void Uart1_Isr(void) interrupt 4
{
if (RI) //检测串口1接收中断
{
command[index] = SBUF;
index++;
uartflag = 1;
RI = 0; //清除串口1接收中断请求位
}
}
void Uart1_Init(void) //1200bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x3C; //设置定时初始值
T2H = 0xF6; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
EA = 1;
}
void sendbyte(unsigned char dat){
SBUF = dat;
while(TI == 0);
TI = 0;
}
void minglingqingchu(){//命令清除
unsigned char i;
for(i = 0;i < 10;i++){
command[i] = '\0';
index = 0;
}
}
void minglingshibie(){//命令识别
if(uartflag2){
if(workmode == 0){
if((command[0] == 'A') && (command[1] == 'A') && (command[2] == 'A') && (command[3] == 'S') && (command[4] == 'S') && (command[5] == 'S')){
printf("{%d-%d%}{%d-%d-%d}{%d}",(int)(temp),(int)(shidu),(int)((rtctime[2] / 16 * 10) + (rtctime[2] % 16)),(int)((rtctime[1] / 16 * 10) + (rtctime[1] % 16)),(int)((rtctime[0] / 16 * 10) + (rtctime[0] % 16)),(int)(jiejin));
}
}
if(workmode == 1){
if((command[0] == 'A') && (command[1] == 'A') && (command[2] == 'A') && (command[3] == 'S') && (command[4] == 'S') && (command[5] == 'S')){
printf("{%d-%d%}{%d-%d-%d}{%d}",(int)(temp),(int)(shidu),(int)((jiejinshijian[2] / 16 * 10) + (jiejinshijian[2] % 16)),(int)((jiejinshijian[1] / 16 * 10) + (jiejinshijian[1] % 16)),(int)((jiejinshijian[0] / 16 * 10) + (jiejinshijian[0] % 16)),(int)(tingliu));
}
}
uartflag2 = 0;
uartcount = 0;
minglingqingchu();
}
}
//************************************
//************************************显示功能
void wendushidujiance(){//温度湿度检测
showsmg(1,Seg_Table[temp / 10]);
showsmg(2,Seg_Table[temp % 10]);
showsmg(3,Seg_Table[12]);
showsmg(6,Seg_Table[shidu / 10]);
showsmg(7,Seg_Table[shidu % 10]);
showsmg(8,0x89);
}
void shishishizhong(){//实时时钟
showsmg(1,Seg_Table[rtctime[2] / 16]);
showsmg(2,Seg_Table[rtctime[2] % 16]);
showsmg(3,Seg_Table[16]);
showsmg(4,Seg_Table[rtctime[1] / 16]);
showsmg(5,Seg_Table[rtctime[1] % 16]);
showsmg(6,Seg_Table[16]);
showsmg(7,Seg_Table[rtctime[0] / 16]);
showsmg(8,Seg_Table[rtctime[0] % 16]);
}
void tingliushijian(){
showsmg(4,Seg_Table[16]);
showsmg(8,Seg_Table[tingliu % 10]);
showsmg(7,Seg_Table[tingliu / 10 % 10]);
showsmg(6,Seg_Table[tingliu / 100 % 10]);
showsmg(5,Seg_Table[tingliu / 1000 % 10]);
}
//************************************
//************************************
void showselect(){
switch(show){
case 0:wendushidujiance();break;
case 1:shishishizhong();break;
case 2:tingliushijian();break;
}
}
//************************************
//************************************LED与EEPROM读写
void led(){
if(jiejin){
flag = 0;
ledstat = ledstat & ~0x04;
}else{
ledstat = ledstat | 0x04;
if(flag == 0){
flag = 1;
tingliu = count / 200;
}
count = 0;
}
if(workmode == 0){
ledstat = ledstat & ~0x01;
}else{
ledstat = ledstat | 0x01;
}
if(workmode == 1){
ledstat = ledstat & ~0x02;
}else{
ledstat = ledstat | 0x02;
}
outputp0(4,ledstat);
}
//************************************
//************************************
void scankey(){
if(P33 == 0){//S4
Delay(de);
while(P33 == 0){
showselect();
}
workmode = ~workmode;
}
if(P32 == 0){//S5
Delay(de);
while(P32 == 0){
showselect();
}
show++;
show %= 3;
}
}
//************************************
void main(){
ds1302config();
initsys();
Uart1_Init();
Timer0_Init();
while(1){
cewen();
light = guangmin();
ceshidu();
led();
jieshijian();
ds1302read();
showselect();
minglingshibie();
scankey();
}
}
char putchar(char ch){
sendbyte(ch);
return ch;
}