成品的电路图什么时候画好还不知道呐,不能再这么拖下去了,先发个帖子整理一下吧。
1、功能说明
使用MAC的电脑将时间数据按指定格式发至单片机,顺便把时间信息显示到屏幕上。
2、模块介绍
ArduinoMini、DS3231时钟模块、IIC显示转换模块、2004LCD外加杜邦线一小堆。
3、成品的样子
4.单片机代码:
Notice:原DS3231函数库有BUG,不要直接套用。
//头文件定义
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <DS3231.h>
//end头文件定义
//宏定义
#define inputStringLength 50
//end宏定义
//变量定义&初始化
DS3231 Clock; // DS3231模块初始化
LiquidCrystal_I2C lcd(0x27, 20, 4); // 显示模块初始化
// 保存时钟数据
byte second, minute, hour;
byte date, month, year;
byte DoW;
float temperature;
bool h12, PM;
bool Century;
byte secondBuffer, minuteBuffer, hourBuffer;
byte dateBuffer, monthBuffer, yearBuffer;
byte DoWBuffer;
float temperatureBuffer;
//串口输入缓存
char inputKeyBuffer[inputStringLength] = "0";
char checkDataBffer[] = "AT99123124606006=#"; // 数据检查样本
// 自定义字符
unsigned char dot[8] = {0x7, 0x5, 0x7}; // 摄氏温标
unsigned char heart[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}; // 心
/end变量定义&初始化
//
void setup() {
h12 = false;
Wire.begin(); // IIC接口启动
Serial.begin(9600); // UART接口启动
lcd.init(); // 显示模块启动
lcd.backlight(); // 开背光
// 创建自定义字符
lcd.createChar(0, dot);
lcd.createChar(1, heart);
}
void loop() {
dispClock(); // 显示时间
setClock4UART(); // 读串口数据,可重入
}
//显示时间函数
void dispClock() {
readClock();
lcd.setCursor(0, 0);
dispWeek();
lcd.setCursor(5, 1);
dispDate();
lcd.setCursor(6, 2);
dispTime();
lcd.setCursor(7, 3);
dispTemp();
}
/end显示时间函数
//读时间函数
void readClock() {
Clock.getTime(year, month, date, DoW, hour, minute, second, h12, PM);
temperature = Clock.getTemperature();
}
///end显示时间函数
// 获取时间日期温度函数
void dispTime() { // 获取时间
if (hour < 10) {
lcd.print('0');
}
lcd.print(hour);
lcd.print(':');
if (minute < 10) {
lcd.print('0');
}
lcd.print(minute);
lcd.print(':');
if (second < 10) {
lcd.print('0');
}
lcd.print(second);
}
void dispDate() { // 获取日期
lcd.print("20");
if (year < 10) {
lcd.print('0');
}
lcd.print(year);
lcd.print('-');
if (month < 10) {
lcd.print('0');
}
lcd.print(month);
lcd.print('-');
if (date < 10) {
lcd.print('0');
}
lcd.print(date);
}
void dispWeek() { // 获取星期
switch (DoW) {
case 0: {
lcd.print(" ");
lcd.write(1);
lcd.print("Monday");
lcd.write(1);
lcd.print(" ");
break;
}
case 1: {
lcd.print(" ");
lcd.write(1);
lcd.print("Tuesday");
lcd.write(1);
lcd.print(" ");
break;
}
case 2: {
lcd.print(" ");
lcd.write(1);
lcd.print("Wednesday");
lcd.write(1);
lcd.print(" ");
break;
}
case 3: {
lcd.print(" ");
lcd.write(1);
lcd.print("Thursday");
lcd.write(1);
lcd.print(" ");
break;
}
case 4: {
lcd.print(" ");
lcd.write(1);
lcd.print("Friday");
lcd.write(1);
lcd.print(" ");
break;
}
case 5: {
lcd.print(" ");
lcd.write(1);
lcd.print("Saturday");
lcd.write(1);
lcd.print(" ");
break;
}
case 6: {
lcd.print(" ");
lcd.write(1);
lcd.print("Sunday");
lcd.write(1);
lcd.print(" ");
break;
}
}
}
void dispTemp() { // 获取温度
lcd.print(temperature);
lcd.write(0);
lcd.print('C');
}
///end获取各种时间函数
// 读串口数据
void setClock4UART() {
if (Serial.available() > 0) {
transtr();
if (!checkData()) {
str2timedata();
setTime();
clearBuffer();
}
}
}
//end读串口数据
//
//
// 获取串口数据处理并保存
// AT年月日时分秒星期#
// AT14030318431201=#
// 012345678901234567 //16
/*
//串口输入缓存
char inputKeyBuffer[inputStringLength] = "0";
char checkDataBffer[] = "AT99123124606006="; // 数据检查样本
*/
void transtr() { // 存数据至缓冲区
Serial.readBytesUntil('#', inputKeyBuffer, 23);
Serial.end();
Serial.begin(9600);
}
bool checkData() { // 判断输入数据是否合法。 true = 合法
if (
((checkDataBffer[0] == inputKeyBuffer[0]) && (checkDataBffer[1] == inputKeyBuffer[1])) &&
(checkDataBffer[16] == inputKeyBuffer[16])
) {
return (true);
} else {
return (false);
}
}
void str2timedata() { // 读串口传来数据至缓存
yearBuffer = str2byte(inputKeyBuffer[2], inputKeyBuffer[3]);
monthBuffer = str2byte(inputKeyBuffer[4], inputKeyBuffer[5]);
dateBuffer = str2byte(inputKeyBuffer[6], inputKeyBuffer[7]);
hourBuffer = str2byte(inputKeyBuffer[8], inputKeyBuffer[9]);
minuteBuffer = str2byte(inputKeyBuffer[10], inputKeyBuffer[11]);
secondBuffer = str2byte(inputKeyBuffer[12], inputKeyBuffer[13]);
DoWBuffer = str2byte(inputKeyBuffer[14], inputKeyBuffer[15]);
}
void setTime() { // 设置时钟模块寄存器
Clock.setSecond(secondBuffer);
Clock.setMinute(minuteBuffer);
Clock.setHour(hourBuffer);
Clock.setDate(dateBuffer);
Clock.setMonth(monthBuffer);
Clock.setYear(yearBuffer);
Clock.setDoW(DoWBuffer);
Serial.println("setOK");
}
byte str2byte(char L, char R) { // 字符转数字
byte temp = (byte)((L - '0') * 10 + (R - '0'));
return temp;
}
void clearBuffer() { // 清缓冲区
int i = 0;
for (int i = 0; i < inputStringLength ; i++)
inputKeyBuffer[i] = (char)0;
}
//end获取串口数据处理并保存
6、使用说明:
把组装好的,通电的单片机连接MAC,同时运行时间同步程序。
7、存在的问题:
咱家完全不会协议栈编程,因此仅仅勉强写了个看起来没问题,实际上BUG泛滥的玩意。以前找的帮我画电路图的人挖洞逃跑了,没办法只好自己画了。因此大家不要期待电路图有完成的一天。我不想也不会把精力放在这方面,因为还有成堆的软件问题等着我去学呢。