本帖最后由 蹦蹦虾 于 2015-1-12 10:56 编辑 方案名称:家居LED显示屏 设计理念:替代家里的传统时钟显示。 功能概述:1.显示采用LED显示模组支持单色、双色、全彩户内灯板。 2.具有时钟显示功能。 3.具有温湿度采集显示功能。 4.具有空气质量传感器采集,显示功能。 5.为了增加可玩性,增加了蓝牙串口通信功能,这样就可以跟手机通信完成更多的功能。 6.增加手机留言功能。 7.增加学习2262,2272编码器功能,这样就可以用手机控制支持2262,2272遥控的家用电器,比如灯光,可遥控插座等。 系统框图 åçæ¡å¾ 配套硬件选择: LED显示屏接口方式比较多,主要是08接口12接口75接口,08接口主要是户内的单元板,12接口是户外模组,75接口是全彩模组。这里先选用比较简单的16扫的户内08接口作为主显示屏。 所以LED引脚在学习板中的硬件引脚定义如下: BusOut outline(PC_14,PC_15,PF_0,PF_1);//行输出选择 DigitalOut ledclk(A0);//时钟 DigitalOut ledst(A1);//锁存 DigitalOut ledoe(A2);//OE极性 DigitalOut ledr1(PC_2);//红色数据1 DigitalOut ledr2(PC_3); DigitalOut ledg1(PC_12);//绿色数据1 DigitalOut ledg2(PD_2); DigitalOut ledb1(PC_10);//蓝色数据1 DigitalOut ledb2(PC_11); 无线接收模块的选择用普通的315M接收发送模块,功能实现起来简单但是只能实现单一频段的发码和收码,支持的设备比较少,CC1101支持ASK,FSK得多种调制方式和灵活的配置寄存器的改变通信频率的方法。如果运用的好的话会支持很多市面上现有的无线通信设备。但是调试难度比较大作为备选方案。 可以用外置的时钟模块,也可以用学习板自带的时钟功能,这个测试看下精度在定。 具体功能会随着调试进程逐渐发布。 2015/1/12 MBED开发现在还不会导出,先贴出部分主函数,并讲解一下大概的思路。 #include "LED_Display.h" #include "Time_Display.h" #include "mbed.h" Ticker RefreshRow,ScreenChange,flipper; DigitalOut led1(LED1); void flip() { led1 = !led1; } LEDScreen led(A0, A1, A2, PC_2, PC_3, PC_12, PD_2, PC_10, PC_11, PC_14, PC_15, A3, A4); SceneContent Area1;//分区1 SystemTime Time1; int main(){ char m; Time1.Time_Set(0,9,12,21,3,114); flipper.attach(&flip, 1.0);//LED led.Screen_Size(32,8,0); Area1.Display_Locale(0,0,16,8,RB0); // m=Area1.DirectScreen(); RefreshRow.attach_us(&led, &LEDScreen::Screen_Refresh, 1000); // the address of the object, member function, and interval while(1) { if(P1_Sign==0){ //幕开始 //设置幕参数 m=Screen_Count1*4; Change_type=Play_content1[0+m];//变化内容 Change_mode=Play_content1[1+m];//变化模式 Change_Speed=Play_content1[2+m];//变化速度 ResidenceTime=Play_content1[3+m]*100;//停留秒数 Area1.GetDisplayData();//获取幕内容 ScreenChange.attach_us(&Area1, &SceneContent::TimingChange, 10000);//开启定时器 P1_Sign=1; if(Screen_Count1>=2) Screen_Count1=0; else Screen_Count1++; } } } 上面2个头文件一个是LED显示屏的设置,一个是主芯片时钟功能设置。 主函数中先设置时间 Ticker RefreshRow,ScreenChange,flipper; 先定义3个定时器,定时中断执行不同的功能。 RefreshRow用来定时刷新LED显示屏,ScreenChange用来更新显示内容。flipper用来定时学习板上的LED指示灯显示。 DigitalOut led1(LED1); 定义学习板上LED指示灯的闪烁引脚定义。void flip() 函数让控制LED指示灯的引脚翻转。 LEDScreen led(A0, A1, A2, PC_2, PC_3, PC_12, PD_2, PC_10, PC_11, PC_14, PC_15, A3, A4); 生成LED显示屏对象 SceneContent Area1;//分区1 生成分区对象 分区的对象的意思是假设显示屏是64*64的点阵我想在上面32*64的点阵显示时间,下面32*64的点阵显示文字,就需要把实际屏体的点阵做好分区。 SystemTime Time1; 生成时间对象 主函数中先设置系统时间。 LED指示灯闪烁的方法 设置屏幕大小的方法 分区的设置,参数分别为起点的X坐标,Y坐标,分区的高,分区的长和读取数据的缓冲区的首地址。 然后再生产一个每隔1MS刷新LED显示屏行数据的方法。 主循环中先从一个节目数组中,读出显示一个分区一幕数据的,变化内容,变化模式,变化速度,和停留时间。 然后获取显示内容,因为在开启变化内容速度的计时器中断方法。P1_Sign1为分区1正在显示标志位。显示结束后会在中断方法中置零。这样就可以显示下一幕数据。下一幕数据标志位为Screen_Count1。 因为时间的问题现在只做了2个节目,一个开机的欢迎画面,一个是显示时间。函数如下: //---------------------- 显示开机画面---------------------------- void SceneContent:isplayDataOfBoot(void) { LoadByteToDisBuf(AsciiCodeTab,'w',0); LoadByteToDisBuf(AsciiCodeTab,'e',1); LoadByteToDisBuf(AsciiCodeTab,'l',2); LoadByteToDisBuf(AsciiCodeTab,'c',3); LoadByteToDisBuf(AsciiCodeTab,'o',4); LoadByteToDisBuf(AsciiCodeTab,'m',5); LoadByteToDisBuf(AsciiCodeTab,'e',6); LoadByteToDisBuf(AsciiCodeTab,' ',7); } /******************************************* * 显示时间 * ********************************************/ void SceneContent:isplayTimeOfToday() { time_t seconds = time(NULL);//获取实时时间 Time[SEC]=char(seconds%60); Time[MIN]=char((seconds/60)%60); Time[HOU]=char((seconds/3600)%24); LoadByteToDisBuf(AsciiCodeTab,Time[SEC]%10+48,7); LoadByteToDisBuf(AsciiCodeTab,Time[SEC]/10+48,6); LoadByteToDisBuf(AsciiCodeTab,':',5); LoadByteToDisBuf(AsciiCodeTab,Time[MIN]%10+48,4); LoadByteToDisBuf(AsciiCodeTab,Time[MIN]/10+48,3); LoadByteToDisBuf(AsciiCodeTab,':',2); LoadByteToDisBuf(AsciiCodeTab,Time[HOU]%10+48,1); LoadByteToDisBuf(AsciiCodeTab,Time[HOU]/10+48,0); } 函数在获取内容中调用函数如下: //----------取出一幕内容到缓冲区 ---------------- //缓冲区首地址,内容类型 void SceneContent::GetDisplayData() { switch(Change_type) //扫描 { case 0x00: DisplayDataOfBoot();break;//欢迎使用 case 0x01: DisplayTimeOfToday();break; //case 0x02: DisplayDateOfToday(addr);break; //case 0x03: DisplayYearOfToday(addr);break; //case 0x04: DisplayWeekOfToday(addr);break; //case 0x05: DisplayOfTemp(addr);break; case 0x06: break; case 0x07: break; case 0x08: break; default: DisplayDataOfBoot();break; } Change_Count=0;//变化计数 Change_sign=1;//进入变化 } 变化的具体方法还没有优化,需要不断调试函数如下: //----------显示一幕变化 ---------------- //显示所在分区位置,分区大小,缓冲区地址,数据内容,变化方式 有溢出风险如果缓冲区大于实际显示面积 char SceneContent:isplayChange() { switch(Change_mode) //变化模式 { case 0x00: Change_Count=DirectScreen();return Change_Count;//变化计数;//立即显示 case 0x01: Change_Count=LeftMoveScreen(Change_Count);return Change_Count;//左移显示 case 0x02: Change_Count=UpCoverScreen(Change_Count);return Change_Count;//上覆盖 case 0x03: Change_Count=DownCoverScreen(Change_Count);return Change_Count;//下覆盖 case 0x04: Change_Count=UpMoveScreen(Change_Count);return Change_Count;//上移 case 0x05: Change_Count=DownMoveScreen(Change_Count);return Change_Count;//下移 //case 0x06: return m; //case 0x07: return m; //case 0x08: return m; default: Change_Count=DirectScreen();return Change_Count;//立即显示 } //根据变化计数,和分区位置。写入显存区 } 因为我的LED显示屏在测试的时候不幸烧了一下,好像烧断了一个行线,现在显示屏只显示上半部分,稍后奉上显示图片。 |
最近一直学习在用MBED开发,进度慢了很多,主要是不太懂类的概念。不过还好逐渐入门了也利用这个机会学习一下C++,显示屏部分快要调试成功了。放一张MBED开发的界面图。
帖子太长了,后续补充一下。
在这里还要求助一个关于MEBD上关于时间的一个问题。关于MEBD中上的文章http://mbed.smeshlink.com/cookbook/32-mbedrtc
先生成一个
结构类型tm,用来记录一个我们能够理解的时间表示,其定义如下,其中的成员包括秒、分、小时、日(一月的第几天)、月、年、日(一星期的第几天)、日(一年的第几天):
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
int main() {
structtm t;
t.tm_sec = 00; // 0-59
t.tm_min = 9; // 0-59
t.tm_hour = 12; // 0-23
t.tm_mday = 21; // 1-31
t.tm_mon = 3; // 0-11
t.tm_year = 114; // year since 1900
// Set RTC time today
set_time(mktime(&t));
}
在主函数中国设置时间
time_t mktime((struct tm *_timeptr))
把tm类型转换成time_t类型
但是调用mktime方法的时候编译通不过,提示没有函数原型。
增加头文件
#include <time.h> 现象一样。 这里想问一下各位怎么能够在MEBD中使用mktime方法呢?
2015/1/12 先上2张调试图片
下半部分还没有设计好。
嘿嘿,还打算用一个串行FLASH存储汉字字库。换一款I2C的时钟芯片,这样UART,SPI,I2C接口就全用到了,因为LED显示屏还需要定时刷新,同时还需要有左移等变化,这样还要用到多个定时器。模拟量也直接用开发板的IO引脚来实现。这样开发板的大部分功能就都可以用上了。
恩,值得一试,加油
用MBED开发好艰难呀,按照我的程序思路,温湿度传感器读取中断的优先级要高于LED显示屏刷新的优先级,在MBED开发环境下也没找到怎么设置中断优先级,而且程序运行一段时间就会莫名其妙的死机,无奈编程环境又变成KEIL,正好有朋友免费提供了一张全彩的LED灯板,功能上没有太多的变化,但是程序大变样改了好多。放几张全彩灯板显示的效果图吧。全彩的LED由红、绿、蓝三色灯组成所以能够显示7种颜色,效果如下:
时钟功能是采用学习板内部的RTC来实现的。可以设置和显示,年、月、日、时、分、秒和星期。