51单片机项目:多功能记录仪

来源:互联网 发布:sql学生成绩表 编辑:程序博客网 时间:2024/05/17 01:36


main.h

/** * 51单片机项目:多功能记录仪 * 文件名:main.h */#ifndef _MAIN_H#define _MAIN_Htypedef struct msg {uint8_t hour;//时uint8_t minute;//分uint8_t second;//秒uint8_t tempIntPart;//温度uint8_t humidity;//湿度uint8_t resTime;//物品停留时间} msg_t;typedef void (* pFn)();//定义函数指针类型void keyAction(uint8_t keyCode);void Serial_receive();void dispMode0();void dispMode1();void dispMode2();void LEDupdate();void LED3toggle();#endif


main.c

/** * 51单片机项目:多功能记录仪 * 工作模式0:自动传输模式(上电默认) * 工作模式1:自动记录模式 * 用户操作: * (1)按键S5切换工作模式 * (2)按键S4切换显示模式 * (3)当记录仪工作在两种模式下时,只有当用户发送字符"AAASSS"给单片机, *      单片机才把数据传送给上位机显示。 *  * 文件名:main.c */#include <stc15f2k60s2.h>#include <string.h>#include "stdint.h"#include "timer.h"#include "digitalTube.h"#include "independentKey.h"#include "Serial.h"#include "I2C.h"#include "EEPROM.h"#include "PCF8591.h"#include "OneWire.h"#include "DS18B20.h"#include "DS1302.h"#include "main.h"sbit LED_1 = P0^0;sbit LED_2 = P0^1;sbit LED_3 = P0^2;volatile bit flag200ms = 0, flag300ms = 0, flag1s = 0;pFn code disptr[3] = { dispMode0, dispMode1, dispMode2 };uint8_t disptrIndex = 0;bit workingMode = 0;//为0表示自动传输模式;为1表示自动记录模式msg_t message;uint8_t SerialBuf[7], SerialBufIndex = 0;void main() {sTime_t time;uint8_t preSec;int16_t temperature;uint8_t tempIntPart, tempDecPart;uint8_t chn1Sample, chn3Sample, cnt300ms = 0;uint8_t EEPROMwritingIndex = 0, EEPROMreadingIndex = 0;bit isShading = 0;tmr0_init(2);DS18B20_start();DS1302init();Serial_init(1200);//baudrate=1200LEDupdate();while (1) {keyDriver();if (flag200ms) {//200ms采集一次实时时间flag200ms = 0;DS1302_getRealTime(&time);if (time.sec != preSec) {//秒有变化message.hour = time.hour;message.minute = time.minute;message.second = time.sec;if (disptrIndex == 0) {dispMode0();}preSec = time.sec;}}if (flag300ms) {//300ms采集一次模拟量flag300ms = 0;chn1Sample = PCF8591_getADCvalue(1);//通道1的采样值chn3Sample = PCF8591_getADCvalue(3);//通道3的采样值message.humidity = (uint8_t)((uint16_t)chn3Sample * 99 / 255);if (chn1Sample < 128) {//如果遮光cnt300ms++;isShading = 1;} else {//没有遮光if (isShading) {//如果之前遮光(上升沿)message.resTime = cnt300ms * 3 / 10;cnt300ms = 0;//本次遮挡完毕,重置计时次数}isShading = 0;}if (disptrIndex == 1) {//如果显示模式是1,则更新湿度显示dspBuf[5] = message.humidity / 10;dspBuf[6] = message.humidity % 10;} else if (disptrIndex == 2) {//如果显示模式是2,则更新物品停留时间显示dspBuf[6] = message.resTime / 10;dspBuf[7] = message.resTime % 10;}}if (flag1s) {//1s采集一次温度flag1s = 0;DS18B20_getTemperature(&temperature);DS18B20_start();//!!!重新启动tempIntPart = getIntPart(temperature);tempDecPart = getDecPart(temperature);if (tempDecPart >= 5)//四舍五入tempIntPart++;message.tempIntPart = tempIntPart;if (disptrIndex == 1) {//如果是显示模式1,则更新温度显示dspBuf[0] = message.tempIntPart / 10;dspBuf[1] = message.tempIntPart % 10;}if (isShading) {//如果被遮光,则LED3一秒钟闪烁一次LED3toggle();}if (workingMode) {//如果工作于自动记录模式EEPROMwrite((uint8_t *)&message, EEPROMwritingIndex, sizeof (msg_t));EEPROMwritingIndex += sizeof (msg_t);//这个EEPROM一共是256字节的存储空间EEPROMread((uint8_t *)&message, EEPROMreadingIndex, sizeof (msg_t));//写入后再读出EEPROMreadingIndex += sizeof (msg_t);}}}}void keyAction(uint8_t keyCode) {switch (keyCode) {case 4:if (disptrIndex == 2) {disptrIndex = 0;} else {disptrIndex++;}disptr[disptrIndex]();break;case 5:workingMode = ~workingMode;LEDupdate();break;}}void Serial_receive() {//uint8_t hour, minute, second;uint8_t hshi, hge, mshi, mge, sshi, sge;uint8_t temshi, temge, humshi, humge;uint8_t restshi, restge;SerialBuf[SerialBufIndex] = SBUF;if (SerialBufIndex == 5) {if (strncmp(SerialBuf, "AAASSS", 6) == 0) {//hour = (message.hour >> 4) * 10 + (message.hour & 0x0F);// 将BCD码解码//minute = (message.minute >> 4) * 10 + (message.minute & 0x0F);//second = (message.second >> 4) * 10 + (message.second & 0x0F);//myprintf("{%hhu-%hhu-%hhu}", hour, minute, second);hshi = message.hour >> 4;hge = message.hour & 0x0F;mshi = message.minute >> 4;mge = message.minute & 0x0F;sshi = message.second >> 4;sge = message.second & 0x0F;temshi = message.tempIntPart / 10;temge = message.tempIntPart % 10;humshi = message.humidity / 10;humge = message.humidity % 10;restshi = message.resTime / 10;restge = message.resTime % 10; myprintf("{%c%c-%c%c-%c%c}", hshi+'0', hge+'0', mshi+'0', mge+'0', sshi+'0', sge+'0');//myprintf("{%hhuC--%hhuH}", message.tempIntPart, message.humidity);myprintf("{%c%cC--%c%cH}", temshi+'0', temge+'0', humshi+'0', humge+'0');if (workingMode == 0) {if (message.resTime)myprintf("{--1--}\n");elsemyprintf("{--0--}\n");} else {//myprintf("{--%hhus}\n", message.resTime);myprintf("{--%c%cs}\n", restshi+'0', restge+'0');//注意要加'0'}}SerialBufIndex = 0;} else {SerialBufIndex++;}}void Serial_transmit() { }void dispMode0() {static bit flag = 0;dspBuf[0] = message.hour >> 4;dspBuf[1] = message.hour & 0x0F;dspBuf[2] = (flag ? 11 : 10);dspBuf[3] = message.minute >> 4;dspBuf[4] = message.minute & 0x0F;dspBuf[5] = (flag ? 11 : 10);dspBuf[6] = message.second >> 4;dspBuf[7] = message.second & 0x0F;flag = ~flag;}void dispMode1() {dspBuf[0] = message.tempIntPart / 10;dspBuf[1] = message.tempIntPart % 10;dspBuf[2] = 12;//CdspBuf[3] = 11;//-dspBuf[4] = 11;//-dspBuf[5] = message.humidity / 10;dspBuf[6] = message.humidity % 10;dspBuf[7] = 13;//H}void dispMode2() {dspBuf[0] = 11;dspBuf[1] = 10;dspBuf[2] = 10;dspBuf[3] = 0;dspBuf[4] = 0;dspBuf[5] = 0;dspBuf[6] = message.resTime / 10;dspBuf[7] = message.resTime % 10;}void LEDupdate() {uint8_t tmp = 0xFF;//初始化为都不显示P2 = (P2 & 0x1F) | 0x80;tmp = P0;//获取对应于LED组件时P0的状态P2 &= 0x1F;tmp |= 0xF8;//高5位都不显示,置1(0有效)tmp &= 0xFC;//最低2位清0if (workingMode == 0) {tmp |= 0x02;//最低2位写10} else {tmp |= 0x01;//最低2位写01}P2 = (P2 & 0x1F) | 0x80;P0 = tmp;P2 &= 0x1F;}/*void LEDupdate() {P2 = (P2 & 0x1F) | 0x80;P0 |= 0xFC;//高位置1,使其无效P2 &= 0x1F;P2 = (P2 & 0x1F) | 0x80;P0 ^= 0x03;P2 &= 0x1F;}*/void LED3toggle() {P2 = (P2 & 0x1F) | 0x80;P0 ^= 0x04;//这里运行的现象有问题,不知道是什么原因//P0 ^= 0xFB;//LED_3 = ~LED_3;P2 &= 0x1F;}void tmr0ISR() interrupt 1 {static uint16_t cnt = 0;TL0 = tmr0LowByte;TH0 = tmr0HighByte;   cnt++;digitalTubeScan();if (cnt & 0x01)keyScan();if (cnt % 100 == 0) {flag200ms = 1;}if  (cnt % 150 == 0) {flag300ms = 1;}if (cnt == 500) {cnt = 0;flag1s = 1;}}




0 0
原创粉丝点击