搜索
bottom↓
回复: 472

本次实践操作考核题,请有兴趣的给个简单代码—-- 157楼给出目前最佳的代码

[复制链接]

出0入0汤圆

发表于 2011-1-17 17:18:18 | 显示全部楼层 |阅读模式
本次实践操作考核题目,请有兴趣的给个简单的代码(CVAVR平台)

各位看官,不要笑,认为是小儿科的DD。因为有许多人在3个小时时间内做不出来。

做出来的,代码也是.......实在说不出口,硬拼出来的。

看哪位能给个好代码吧。

参考电路:

(原文件名:未标题-1 拷贝.jpg)

忙着吃晚饭,题目没有贴上:
点击此处下载 ourdev_611855K7IZ9G.pdf(文件大小:307K) (原文件名:2010《AVR单片机与嵌入式系统》期末实验考试B.pdf)

=====================================================
原发的是一个草稿,现在已经换上新的,主要是配合上面贴图。

原来是:PA、PB控制8*8LED,要加按键,使用PORTC.0口

操作测试中,为了下载方便,改成:PA、PC控制8*8LED,与贴图相同。要加按键,使用PORTD.0口

我的挑战不要求做按键,只要做出第1部分。

=========================================================
我的代码在157楼,接受各位挑战

有兴趣,把考题做一遍,讨论出个标准答案。。。。。。。。挑战ing....

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2011-1-17 19:31:38 | 显示全部楼层
老马呀, 你都觉得许多人在3个小时时间内做不出来,还要让学生们在两个小时内做出来,要求是不是高了些?

出0入0汤圆

 楼主| 发表于 2011-1-17 19:59:15 | 显示全部楼层
回复【1楼】ywl0409 老黄牛
老马呀, 你都觉得许多人在3个小时时间内做不出来,还要让学生们在两个小时内做出来,要求是不是高了些?
-----------------------------------------------------------------------

这个是已经测试过的题目,最快的学生1个多小时就完成了,当然程序并不一定漂亮,效率和方法都是最笨的,但效果出来了。

楼上的,是玩这个行当吗?你看看题目和要求,你认为华东师范大学(也算全国重点)的通信工程系3年级上的本科生,做这个DD,应该能,还是不能?

出0入0汤圆

发表于 2011-1-17 20:13:48 | 显示全部楼层
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二

出0入0汤圆

 楼主| 发表于 2011-1-17 20:27:59 | 显示全部楼层
回复【3楼】twoperson
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二
-----------------------------------------------------------------------

哪个学校的?不错。我题目的要求时2个小时内完成1 或 2,不是和。当然对于会的人,1和2实际没有太大的差别了。

您是老师还是学生,能帖上个比较不错的代码例子吗?空口无评吗。

出0入0汤圆

发表于 2011-1-17 20:52:22 | 显示全部楼层
回复【4楼】machao
回复【3楼】twoperson  
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二
-----------------------------------------------------------------------
哪个学校的?不错。我题目的要求时2个小时内完成1 或 2,不是和。当然对于会的人,1和2实际没有太大的差别了。
您是老师还是学生,能帖上个比较不错的代码例子吗?空口无评吗。
-----------------------------------------------------------------------

我是计算机系研究生,把这个帖转到了学校bbs上,有俩人这么讨论的

发信人: Tariel (塔里埃尔), 信区: ElecDIY
标  题: Re: 华东师大某大三专业课考题
发信站: 北大未名站 (2011年01月17日20:48:22 星期一), 转信

第一点要干这么四个事情:
1. 设计一个0.2s步进的定时器并甩出中断服务函数. 这个大约需要5min
2. 设计一个东西, 作用是点亮或者熄灭(0,0)到(7,7)里面的任何一个点. 这个大约需要
10min
3. 设计一个东西, 已知亮的那个灯现在的位置, 求下一个亮灯的位置. 这个大约需要
10min. 因为要拐弯, 所以要特别注意.
4. 设计一个东西, 把它们串起来. 这个大概需要5min

第二点用不了半个小时, 就不说了!

【 在 rap (:ica(Happy New Year~) 的大作中提到: 】
: 第一点半小时,第二点半小时,当然我是说,算上看datashit和犯SB错误的时间,且不
: 用仿真器。。。。。。
: 用仿真器的话,第一点一小时,第二点一小时。。。。。。

出0入0汤圆

 楼主| 发表于 2011-1-17 21:18:08 | 显示全部楼层
纸上谈兵容易,实际做一下,贴上个代码。

我做这个的时间:

1。抽了2只烟,想总体结构,以及如何用最方便的方法实现。化了15min.
2。编写代码,10min
3。在实验板上联线搭电路,下载代码,5min。

4。上电,OK了。没有做任何调试。

出0入0汤圆

发表于 2011-1-17 21:21:59 | 显示全部楼层
回复【2楼】machao
-----------------------------------------------------------------------

根据我对现在学生们的水平估计,能够在两个小时内做出来的,最多一半的同学.

出0入0汤圆

发表于 2011-1-17 21:32:07 | 显示全部楼层
具体在哪个点用除和余运算,至于具体点亮哪个的就用查表。。看到这个题目,想到的土办法

出0入0汤圆

发表于 2011-1-17 21:35:22 | 显示全部楼层
大体思路是5楼我转的帖里描述的,估计此人想这个事情应该是一遍想一遍打字,写代码的能力,电子系的人跟计算机系一起上的计算概论,程序设计实习以及算法和数据结构,写个小的C程序不成问题
关键在于同样是重点高校,师范类院校和综合性大学或者理工类大学的电子系水平还是不能比。。。。

出0入0汤圆

 楼主| 发表于 2011-1-17 21:38:36 | 显示全部楼层
回复【5楼】twoperson
回复【4楼】machao  
回复【3楼】twoperson   
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二  
-----------------------------------------------------------------------  
哪个学校的?不错。我题目的要求时2个小时内完成1 或 2,不是和。当然对于会的人,1和2实际没有太大的差别了。  
您是老师还是学生,能帖上个比较不错的代码例子吗?空口无评吗。
-----------------------------------------------------------------------
我是计算机系研究生,把这个帖转到了学校bbs上,有俩人这么讨论的
发信人: tariel (塔里埃尔), 信区: elecdiy
标  题: re: 华东师大某大三专业课考题
发信站: ......
-----------------------------------------------------------------------

再转到贵校的BBS上,说华师大的mou老师发出挑战,就这个题目的第1部分,按键不加,时间不记,上几个简单漂亮的代码。然后我把我的代码贴上,供大家评判。

评判指标:
1。简单、短小,易懂,结构好,层次清楚
2。效率高(指仅化费做这点事情所使用的CPU效率,省出的时间可以睡觉,做其它事情)
3。非常容易调整移动的时间(指改变其中1句或2句代码,或某个变量,其实是为按键调整控制做准备的)
4。显示亮度均匀,没有闪烁、拖尾现象

先给点小压力:我完成第一部分的代码量为(cvavr平台):

Program size: 256 words (512 bytes), 3.1% of FLASH

出0入0汤圆

发表于 2011-1-17 21:46:27 | 显示全部楼层
回复【10楼】machao
回复【5楼】twoperson  
回复【4楼】machao   
回复【3楼】twoperson   
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二   
-----------------------------------------------------------------------   
哪个学校的?不错。我题目的要求时2个小时内完成1 或 2,不是和。当然对于会的人,1和2实际没有太大的差别了。   
您是老师还是学生,能帖上个比较不错的代码例子吗?空口无评吗。  
-----------------------------------------------------------------------  
我是计算机系研究生,把这个帖转到了学校bbs上,有俩人这么讨论的  
发信人: tariel (塔里埃尔), 信区: elecdiy  
标 ......
-----------------------------------------------------------------------

应该没啥人会理。。。
顺便说一句,我们这里一般这类课程考试都是自拟题目,给两周到一个月的时间完成,然后抽一两堂课展示一下再写个报告,评分一般是定一个难度的下限,然后按照题目的难度和完成度给个分
很少会有老师会指定一个考题,建议马老师回头试试这样弄,应该会有点新鲜的东西出现

出0入0汤圆

 楼主| 发表于 2011-1-17 21:46:49 | 显示全部楼层
回复【9楼】twoperson
大体思路是5楼我转的帖里描述的,估计此人想这个事情应该是一遍想一遍打字,写代码的能力,电子系的人跟计算机系一起上的计算概论,程序设计实习以及算法和数据结构,写个小的c程序不成问题
关键在于同样是重点高校,师范类院校和综合性大学或者理工类大学的电子系水平还是不能比。。。。
-----------------------------------------------------------------------

我们这个学院,是非师范专业的。到是想了解理工类大学的电子系水平如何,看你的帖子,贵校也是全国重点。上个大名。

说句实在话,我个人认为全国高校在这个课程上的教学水平都是一般般的。(准备挨砖拍了,不过还是不怕)

出0入0汤圆

 楼主| 发表于 2011-1-17 22:00:23 | 显示全部楼层
回复【11楼】twoperson

顺便说一句,我们这里一般这类课程考试都是自拟题目,给两周到一个月的时间完成,然后抽一两堂课展示一下再写个报告,评分一般是定一个难度的下限,然后按照题目的难度和完成度给个分
很少会有老师会指定一个考题,建议马老师回头试试这样弄,应该会有点新鲜的东西出现
-----------------------------------------------------------------------

扯淡吧。

    我这个学期,上研究生的课。最后的要求就是用M16读SD卡,读取和播放WAWE文件。一个学期,10个研究生(有3个是本校上来的,其它7个是外校考上的)一起讨论,最后大家是相同的,勉强播放一个8K、8位的WAVE文件,按键还不能起作用。

    我给了他们关于SD卡、FAT文件系统所有的参考资料和参考代码,还有日本人做的相同东西的源代码,上课还把相关的知识都介绍了一便。

    推荐他们到一个公司去实习,编写一些与硬件相关的代码,人家给费用,他们一个人也不敢去。彻底失败的感觉!

出0入0汤圆

发表于 2011-1-17 22:12:17 | 显示全部楼层
本人_大三自动化专业,可以肯定我们班没几个人可以在3小时内做出来!

出0入0汤圆

发表于 2011-1-17 22:31:37 | 显示全部楼层
回复【12楼】machao
回复【9楼】twoperson  
大体思路是5楼我转的帖里描述的,估计此人想这个事情应该是一遍想一遍打字,写代码的能力,电子系的人跟计算机系一起上的计算概论,程序设计实习以及算法和数据结构,写个小的c程序不成问题  
关键在于同样是重点高校,师范类院校和综合性大学或者理工类大学的电子系水平还是不能比。。。。
-----------------------------------------------------------------------
我们这个学院,是非师范专业的。到是想了解理工类大学的电子系水平如何,看你的帖子,贵校也是全国重点。上个大名。
说句实在话,我个人认为全国高校在这个课程上的教学水平都是一般般的。(准备挨砖拍了,不过还是不怕)
-----------------------------------------------------------------------

我校是综合大学,北京大学。。。。据我所知,跟单片机直接有关的课,一个是微机原理实验中有一半是在8051的实验板上完成的,之前没有理论介绍,自学;另一个是Cypress公司赞助的,用PSoC的实验课,两门课最后的考试都是自定题目做个自认为好玩的东西交上去
接下来就都把单片机当工具用,默认学生至少会一种了,大多数学生大三就进实验室参加科研了

出0入0汤圆

 楼主| 发表于 2011-1-17 22:32:32 | 显示全部楼层
回复【3楼】twoperson
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二
-----------------------------------------------------------------------

应该没啥人会理。。。
顺便说一句,我们这里一般这类课程考试都是自拟题目,给两周到一个月的时间完成,然后抽一两堂课展示一下再写个报告,评分一般是定一个难度的下限,然后按照题目的难度和完成度给个分
很少会有老师会指定一个考题,建议马老师回头试试这样弄,应该会有点新鲜的东西出现
-----------------------------------------------------------------------

有又一些失败的感觉。这个DD不需要两周到一个月吧,一天可以吗?

我老夫如此嚣张,拿个小儿科的东西出来耍,年轻人应该有点勇气的吧。再说你们知道我是谁,可没有人知道你是谁。连学校的大名都不敢透露。

失败!太失败了!

出0入0汤圆

发表于 2011-1-17 22:38:00 | 显示全部楼层
回复【16楼】machao
回复【3楼】twoperson  
我表示我校绝大部分电子系3年级学生应该能在2小时内完成一和二
-----------------------------------------------------------------------
应该没啥人会理。。。  
顺便说一句,我们这里一般这类课程考试都是自拟题目,给两周到一个月的时间完成,然后抽一两堂课展示一下再写个报告,评分一般是定一个难度的下限,然后按照题目的难度和完成度给个分  
很少会有老师会指定一个考题,建议马老师回头试试这样弄,应该会有点新鲜的东西出现  
-----------------------------------------------------------------------
有又一些失败的感觉。这个dd不需要两周到一个月吧,一天可以吗?
我老夫如此嚣张,拿个小儿科的东西出来耍,年轻人应该有点勇......
-----------------------------------------------------------------------

谁最后做这个事情不是找挂么。。。。
学校名字在5楼有提示,转的bbs帖子里有个发信站,15楼明确说了,比马老师的帖早了1分钟不到,估计是你我同时编辑

出0入0汤圆

 楼主| 发表于 2011-1-17 22:42:39 | 显示全部楼层
回复【15楼】twoperson
北京大学。。。。据我所知,跟单片机直接有关的课,一个是微机原理实验中有一半是在8051的实验板上完成的,之前没有理论介绍,自学;另一个是Cypress公司赞助的,用PSoC的实验课,两门课最后的考试都是自定题目做个自认为好玩的东西交上去
接下来就都把单片机当工具用,默认学生至少会一种了,大多数学生大三就进实验室参加科研了
-------------------------------------------------------------

北大!太刺激了,太兴奋了!有缘分!

就挑战北大的学生,包括研究生。51的代码也行,反正都是C代码,结构思路都一样。

跟我做本科毕业论文的学生,我们专业第一名,09年直升到北大的,他的本科毕业设计就是用一片PSOC的芯片做一个PSOC的编程下载线。

出0入0汤圆

 楼主| 发表于 2011-1-17 22:53:25 | 显示全部楼层
回复【17楼】twoperson
谁最后做这个事情不是找挂么。。。。
-------------------------------------------------

太失败了,这是北大学生吗?不象。

北大、清华,在中国说出来地都会抖上三抖的,学生会怕找挂?

况且,谁知道你是谁?是怕丢北大的脸吗?

如果真是北大的,恐怕这已经无颜了。

出0入0汤圆

发表于 2011-1-17 23:16:51 | 显示全部楼层
坐等马老师的实验程序,准备考好试了自己也试一下

出0入0汤圆

发表于 2011-1-17 23:17:31 | 显示全部楼层
回复【19楼】machao
回复【17楼】twoperson  
谁最后做这个事情不是找挂么。。。。  
-------------------------------------------------
太失败了,这是北大学生吗?不象。
北大、清华,在中国说出来地都会抖上三抖的,学生会怕找挂?
况且,谁知道你是谁?是怕丢北大的脸吗?
如果真是北大的,恐怕这已经无颜了。

-----------------------------------------------------------------------

我理解成你说课程最后的项目做个类似你考试题目的东西了。。。。
这东西的思路不就是两个定时器,一个用来控制T,另一个用来控制扫描数码管,然后数码管扫描分成两个状态,一个状态亮中间四个LED,另一个亮周边的那圈灯,然后设两个volatile变量存着该亮哪个数码管,在第一个定时器的中断里算一下那两个变量么。。。然后算那两个变量查表或者算一下都行

出0入0汤圆

发表于 2011-1-17 23:24:05 | 显示全部楼层
回复【19楼】machao
-----------------------------------------------------------------------

马老师您别和北大的学长争了,人家都研究生了,做这个的确是一没心思,二也的确是理论经验大于实践经验,交给我们华师大的学生吧,您教的班级的庄欣浩会给您个满意的结果的。。

出0入0汤圆

 楼主| 发表于 2011-1-17 23:29:18 | 显示全部楼层
回复【21楼】twoperson
回复【19楼】machao  
回复【17楼】twoperson   
谁最后做这个事情不是找挂么。。。。   
-------------------------------------------------  
太失败了,这是北大学生吗?不象。  
北大、清华,在中国说出来地都会抖上三抖的,学生会怕找挂?  
况且,谁知道你是谁?是怕丢北大的脸吗?  
如果真是北大的,恐怕这已经无颜了。  
-----------------------------------------------------------------------
我理解成你说课程最后的项目做个类似你考试题目的东西了。。。。
这东西的思路不就是两个定时器,一个用来控制t,另一个用来控制扫描数码管,然后数码管扫描分成两个状态,一个状态亮中间四个led,另一个亮周边的那圈灯,然后设两个volatile变量存着该亮哪......
-----------------------------------------------------------------------

废话少说,上代码。
看到使用2个定时器,就已经知道你的水平程度。还是用事实说话吧。

出0入0汤圆

发表于 2011-1-17 23:33:11 | 显示全部楼层
回复【22楼】wangzheyu  
-----------------------------------------------------------------------

你个阿武乱把我说出来干什么

出0入0汤圆

 楼主| 发表于 2011-1-17 23:38:30 | 显示全部楼层
回复【22楼】wangzheyu
回复【19楼】machao  
-----------------------------------------------------------------------
马老师您别和北大的学长争了,人家都研究生了,做这个的确是一没心思,二也的确是理论经验大于实践经验,交给我们华师大的学生吧,您教的班级的庄欣浩会给您个满意的结果的。。
-----------------------------------------------------------------------

班上有2个学生在办公室看过我的代码,我还做了简单的解释,不知道庄是否是其中之一。为什么你不尝试一下呢?

出0入0汤圆

发表于 2011-1-17 23:41:17 | 显示全部楼层
回复【26楼】machao  
-----------------------------------------------------------------------

不 那应该是蒋天宇和夏俊晨 庄是我们班的理论帝

出0入0汤圆

发表于 2011-1-18 00:17:42 | 显示全部楼层
哈哈,看我的代码,高级短小
#include <mega16.h>
flash unsigned char led_7[28]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80};
flash unsigned char position[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
flash unsigned char pos[28]={0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd};

int i;
int        time_counter;                                // 中断次数计数单元
unsigned char        posit;

void display(void)                                // 点阵动态扫描函数
{
        PORTC = 0xff;
        PORTC = position[posit];
        if((PORTC==0xef)||(PORTC==0xf7)){
              if(PORTC==pos){PORTA=0x18|(led_7);}
              else  PORTA=0x18; }
        else if(PORTC==pos){PORTA=0x00|(led_7);}
        else PORTA=0x00;
        if (++posit >=8 ) posit = 0;
}

// Timer 0 比较匹配中断服务
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
        display();                                  // 调用LED扫描显示
        if (++time_counter>=100)
        {
                time_counter = 0;
                if(++i>=28)i=0;
        }
}


void main(void)
{
        PORTA=0x00;                                // 显示控制I/O端口初始化
        DDRA=0xFF;
        PORTC=0xFF;
        DDRC=0xFF;
        // T/C0 初始化
        TCCR0=0x0B;                                // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
        TCNT0=0x00;
        OCR0=0x7C;                         // OCR0 = 0x7C(124),(124+1)/62.5=2ms
        TIMSK=0x02;                                // 允许T/C0比较匹配中断

        posit = 0;


        #asm("sei")                                // 开放全局中断

        while (1)
        {};}

出0入0汤圆

 楼主| 发表于 2011-1-18 00:47:57 | 显示全部楼层
电影剧本:三国片段。

场景:魏蜀两国大军在某地相逢。

1。两军首领在阵前叫阵,蜀国领军人物为老将黄忠,横刀立马,大叫:是骡子是马,拉出来骝骝。

2。魏国首领拿出一个沙盘,与手下几员大将在沙盘上比画比画,说到,我们如此攻击,已经赢了你们。

3。话音刚落,只见蜀国_军中,闪出两员小将,也在手中的沙盘上比画几下,说到,让我们来解决,这样进攻肯定可以。

4。此时天色已黑,双方各退10里,打灶支锅,养精蓄锐,准备改日决出雌雄。

要知后事如何,请听下回分解。。。。。。

======================================================
小记:明天(已经是今天了)10:30考试,今天下午答疑也只来3个女生。怕有学生在此问问题,所以坚守在此。
可惜,还是只有上午的2个问题,没有其它的出现。

无聊之下,编写此段剧本上演。没想碰到北大(或许假冒,未知),精神一振,提刀上马,吼了几声,年轻小儿便被唬怕了。可能是回去搬兵,希望有精兵强将出现,不要偃旗息鼓,否则就没有高潮了。

出0入0汤圆

 楼主| 发表于 2011-1-18 00:53:09 | 显示全部楼层
奇怪:

24、25、27、28、29楼的东西怎么没有了?自己撤掉了?

出0入0汤圆

 楼主| 发表于 2011-1-18 00:58:08 | 显示全部楼层
33楼,下面把32楼的内容删掉。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:01:48 | 显示全部楼层
果然32楼没有了。

有逃兵?!汗。

这个剧本实在有意思。至少蜀国小将的东西没有了。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:02:36 | 显示全部楼层
哈哈哈哈!

出0入0汤圆

 楼主| 发表于 2011-1-18 01:32:51 | 显示全部楼层
to wangzheyu、twoperson两位后生:

是华师大和北大的吗?具体人不知道,但可不能给华师大、北大丢人。

有清华的学生吗?

我豁上去了。一块砖是砸,两快砖也是砸,试试自己的头有多硬。

压力再增加:贴上代码的,如果是在校学生,不管是本科还是研究生,请把所就读学校的大名也贴上。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:38:51 | 显示全部楼层
继续出现逃兵:36、37楼又不见了。

好玩,痛快。

32楼内容是我自己写的测试贴,然后把它删掉的,所以32楼没有了。其它都是发贴人自己删的。现在已经有7个贴自己不见了。

是在调试代码吗?

不要顾及时间了,调试正确再贴吧。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:40:38 | 显示全部楼层
再坚持20分钟,2点睡觉。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:51:03 | 显示全部楼层
再扔出一个唬人的DD:本人是普通高等教育“十一五”国家级规划教材《AVR单片机嵌入式系统原理与应用实践》一书的作者。

8*8点阵的例子书中有,所教学生做过8*8点阵的实验,是规定的实验,并且在考核中学生可以看任何的参考和代码。

北大的后生可以参考此书,了解偶的套路,然后写出更好的代码。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:54:16 | 显示全部楼层
我把此贴置顶。

出0入0汤圆

 楼主| 发表于 2011-1-18 01:59:28 | 显示全部楼层
敢于在下面贴上代码的,如果是在校学生,不管是本科还是研究生,请把所就读学校的大名也贴上。

出0入0汤圆

发表于 2011-1-18 02:36:02 | 显示全部楼层
很像我当初大学时数电实验的题目
不同是:
(1)多一个功能,反转
(2)用的是FPGA

一个班也就10%左右的人能独立做出来吧

出0入0汤圆

 楼主| 发表于 2011-1-18 02:54:53 | 显示全部楼层
回复【44楼】ellison909
很像我当初大学时数电实验的题目
不同是:
(1)多一个功能,反转
(2)用的是fpga
一个班也就10%左右的人能独立做出来吧
-----------------------------------------------------------------------

什么大学的?牛!数电实验用FPGA了。我们的大学培养了太多的高级傻瓜,90%的都是泡沫。

其实不管用什么,FPGA、DSP、还是MCU,思路基本是一样的。

出0入0汤圆

发表于 2011-1-18 03:26:30 | 显示全部楼层
晕倒,马老师辛苦了,注意休息!

出0入42汤圆

发表于 2011-1-18 03:28:30 | 显示全部楼层
void goNext(void{
    if (col==0)
    {
        row<7? ++row: ++col;
    }
    else if (col == 7)
    {
        row>0? --row: --col;
    }
    else
    {
        row==0? --col: ++col;
    }
}

出0入42汤圆

发表于 2011-1-18 03:28:50 | 显示全部楼层
剩下的都不会了....

出0入0汤圆

发表于 2011-1-18 06:10:56 | 显示全部楼层
放到定时器中断里面
interrupt 0
{
    row_pre=row;col_pre=col;
    if(row==0&&col<7)col++;
    else if(col==7&&row<7)row++;
    else if(row==7&&col!=0)col--;
    else if(col==0&&row!=0)row--;
    else {row=0;col=0;};//计算下一个坐标
    {//==================================
       根据坐标更新显示内容:也即擦除上一个点(row_pre,col_pre),写亮下一个点(row,col)
    }
}

出0入4汤圆

发表于 2011-1-18 08:27:12 | 显示全部楼层
最简单的办法是把28帧的数据算出来做成表格,然后程序里把每帧的数据显示你要求的时间就可以。什么坐标计算的都是浮云

出0入0汤圆

发表于 2011-1-18 08:29:31 | 显示全部楼层
这个东西我在毕业设计时做过(当时做的是双色点阵屏,是128X64的),对这个设计,我简单地谈下我的设计思路:
开辟一个缓冲 unsigned char Buffer[1][8];其中每一位对应其中一个LED状态
1、驱动部分设计:
   驱动级里面搞一个定时器,每隔 t ms钟刷新一行点阵数据(共8行轮流刷新)
   假如一秒钟刷新屏幕26次,则:t = 1000/26/8

2、应用部分设计:
   实现一个打点函数,把UCGUI里面的东东集成进来,很简单

以上是设计思路可以应用到LCD驱动设计当中,我目前就是这样用的。只是LCD不需要经常刷新,只要数据变动的时候刷新即可。

出0入0汤圆

发表于 2011-1-18 08:33:52 | 显示全部楼层
上传代码:

/*--------------File Info-------------------------------------------------------
** 文   件   名:  IndoorModule.c
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  户内LED模组驱动函数                       
**------------------------------------------------------------------------------
** Created   by:  JJX                  
** Created date:         
*******************************************************************************/
#include "config.h"
#include "GUI.h"

INT8U Module_Red1Buffer[InMODULE_NUM][32];
INT8U Module_Red2Buffer[InMODULE_NUM][32];
INT8U Module_Green1Buffer[InMODULE_NUM][32];
INT8U Module_Green2Buffer[InMODULE_NUM][32];

//定时器调用
INT8U LCD_Red1Buffer[InMODULE_NUM][32];
INT8U LCD_Red2Buffer[InMODULE_NUM][32];
INT8U LCD_Green1Buffer[InMODULE_NUM][32];
INT8U LCD_Green2Buffer[InMODULE_NUM][32];

void IndoorShift(INT8U red1,INT8U red2,INT8U green1,INT8U green2)
{
    INT8U i;
                            
    for(i=8;i>0;i--)
    {
        IndoorCLK_low();
                    
        if((red1&0x80)==0)
                    IndoorR1_high();         
        else
                    IndoorR1_low();
               
                if((red2&0x80)==0)
                    IndoorR2_high();         
        else
                    IndoorR2_low();

                if((green1&0x80)==0)
                    IndoorG1_high();         
        else
                    IndoorG1_low();

                if((green2&0x80)==0)
                    IndoorG2_high();         
        else
                    IndoorG2_low();
                       
        IndoorCLK_high();
                                        
        red1=red1<<1;
                red2=red2<<1;
                green1=green1<<1;  
                green2=green2<<1;        
    }                 
}

//输出行线状态ABCD (A低,D高)
void hc138scan(INT8U l)
{   
    if(l&0x01) IndoorLA_high();
        else IndoorLA_low();   
       
        if(l&0x02) IndoorLB_high();
        else IndoorLB_low();

        if(l&0x04) IndoorLC_high();
        else IndoorLC_low();

        if(l&0x08) IndoorLD_high();
        else IndoorLD_low();
}

//打点函数。本函数实现与驱动有关,要理解程序请参考驱动电路图
void Indoor_DrawPoint(INT16S x0,INT16S y0,INT8U color)
{
    INT8U module,m;
   
        if( (x0<0)||(x0>=GUI_XWORD*16) ) return;
        if( (y0<0)||(y0>=GUI_YWORD*16) ) return;

    if(GUI_XWORD>IndoorLCD_XSIZE/16) return;
        if(GUI_YWORD>IndoorLCD_YSIZE/16) return;

        module=GUI_XWORD-1-(x0/16);

        x0=x0%16;
       
        y0=y0%32;
        if(y0>=16) m=y0-16;

        if(color==Red)
        {
            if(y0<16)
                switch(x0)
            {
                case 0 :Module_Red1Buffer[module][2*y0]  |=0x80; break;
                    case 1 :Module_Red1Buffer[module][2*y0]  |=0x40; break;
                    case 2 :Module_Red1Buffer[module][2*y0]  |=0x20; break;
                    case 3 :Module_Red1Buffer[module][2*y0]  |=0x10; break;
                    case 4 :Module_Red1Buffer[module][2*y0]  |=0x08; break;
                    case 5 :Module_Red1Buffer[module][2*y0]  |=0x04; break;
                    case 6 :Module_Red1Buffer[module][2*y0]  |=0x02; break;
                    case 7 :Module_Red1Buffer[module][2*y0]  |=0x01; break;

                    case 8 :Module_Red1Buffer[module][2*y0+1]|=0x80; break;
                    case 9 :Module_Red1Buffer[module][2*y0+1]|=0x40; break;
                    case 10:Module_Red1Buffer[module][2*y0+1]|=0x20; break;
                    case 11:Module_Red1Buffer[module][2*y0+1]|=0x10; break;
                    case 12:Module_Red1Buffer[module][2*y0+1]|=0x08; break;
                    case 13:Module_Red1Buffer[module][2*y0+1]|=0x04; break;
                    case 14:Module_Red1Buffer[module][2*y0+1]|=0x02; break;
                    case 15:Module_Red1Buffer[module][2*y0+1]|=0x01; break;
                    default:break;
            }
                else
                switch(x0)
            {
                case 0 :Module_Red2Buffer[module][2*m]  |=0x80; break;
                    case 1 :Module_Red2Buffer[module][2*m]  |=0x40; break;
                    case 2 :Module_Red2Buffer[module][2*m]  |=0x20; break;
                    case 3 :Module_Red2Buffer[module][2*m]  |=0x10; break;
                    case 4 :Module_Red2Buffer[module][2*m]  |=0x08; break;
                    case 5 :Module_Red2Buffer[module][2*m]  |=0x04; break;
                    case 6 :Module_Red2Buffer[module][2*m]  |=0x02; break;
                    case 7 :Module_Red2Buffer[module][2*m]  |=0x01; break;

                    case 8 :Module_Red2Buffer[module][2*m+1]|=0x80; break;
                    case 9 :Module_Red2Buffer[module][2*m+1]|=0x40; break;
                    case 10:Module_Red2Buffer[module][2*m+1]|=0x20; break;
                    case 11:Module_Red2Buffer[module][2*m+1]|=0x10; break;
                    case 12:Module_Red2Buffer[module][2*m+1]|=0x08; break;
                    case 13:Module_Red2Buffer[module][2*m+1]|=0x04; break;
                    case 14:Module_Red2Buffer[module][2*m+1]|=0x02; break;
                    case 15:Module_Red2Buffer[module][2*m+1]|=0x01; break;
                    default:break;
            }
    }
        else if(color==ClearRed)
        {
            if(y0<16)
                switch(x0)
            {
                case 0 :Module_Red1Buffer[module][2*y0]  &=~0x80; break;
                    case 1 :Module_Red1Buffer[module][2*y0]  &=~0x40; break;
                    case 2 :Module_Red1Buffer[module][2*y0]  &=~0x20; break;
                    case 3 :Module_Red1Buffer[module][2*y0]  &=~0x10; break;
                    case 4 :Module_Red1Buffer[module][2*y0]  &=~0x08; break;
                    case 5 :Module_Red1Buffer[module][2*y0]  &=~0x04; break;
                    case 6 :Module_Red1Buffer[module][2*y0]  &=~0x02; break;
                    case 7 :Module_Red1Buffer[module][2*y0]  &=~0x01; break;

                    case 8 :Module_Red1Buffer[module][2*y0+1]&=~0x80; break;
                    case 9 :Module_Red1Buffer[module][2*y0+1]&=~0x40; break;
                    case 10:Module_Red1Buffer[module][2*y0+1]&=~0x20; break;
                    case 11:Module_Red1Buffer[module][2*y0+1]&=~0x10; break;
                    case 12:Module_Red1Buffer[module][2*y0+1]&=~0x08; break;
                    case 13:Module_Red1Buffer[module][2*y0+1]&=~0x04; break;
                    case 14:Module_Red1Buffer[module][2*y0+1]&=~0x02; break;
                    case 15:Module_Red1Buffer[module][2*y0+1]&=~0x01; break;
                    default:break;
            }
                else
                switch(x0)
            {
                case 0 :Module_Red2Buffer[module][2*m]  &=~0x80; break;
                    case 1 :Module_Red2Buffer[module][2*m]  &=~0x40; break;
                    case 2 :Module_Red2Buffer[module][2*m]  &=~0x20; break;
                    case 3 :Module_Red2Buffer[module][2*m]  &=~0x10; break;
                    case 4 :Module_Red2Buffer[module][2*m]  &=~0x08; break;
                    case 5 :Module_Red2Buffer[module][2*m]  &=~0x04; break;
                    case 6 :Module_Red2Buffer[module][2*m]  &=~0x02; break;
                    case 7 :Module_Red2Buffer[module][2*m]  &=~0x01; break;

                    case 8 :Module_Red2Buffer[module][2*m+1]&=~0x80; break;
                    case 9 :Module_Red2Buffer[module][2*m+1]&=~0x40; break;
                    case 10:Module_Red2Buffer[module][2*m+1]&=~0x20; break;
                    case 11:Module_Red2Buffer[module][2*m+1]&=~0x10; break;
                    case 12:Module_Red2Buffer[module][2*m+1]&=~0x08; break;
                    case 13:Module_Red2Buffer[module][2*m+1]&=~0x04; break;
                    case 14:Module_Red2Buffer[module][2*m+1]&=~0x02; break;
                    case 15:Module_Red2Buffer[module][2*m+1]&=~0x01; break;
                    default:break;
            }
    }
       
        else if(color==Green)
        {
            if(y0<16)
                switch(x0)
            {
                case 0 :Module_Green1Buffer[module][2*y0]  |=0x80; break;
                    case 1 :Module_Green1Buffer[module][2*y0]  |=0x40; break;
                    case 2 :Module_Green1Buffer[module][2*y0]  |=0x20; break;
                    case 3 :Module_Green1Buffer[module][2*y0]  |=0x10; break;
                    case 4 :Module_Green1Buffer[module][2*y0]  |=0x08; break;
                    case 5 :Module_Green1Buffer[module][2*y0]  |=0x04; break;
                    case 6 :Module_Green1Buffer[module][2*y0]  |=0x02; break;
                    case 7 :Module_Green1Buffer[module][2*y0]  |=0x01; break;

                    case 8 :Module_Green1Buffer[module][2*y0+1]|=0x80; break;
                    case 9 :Module_Green1Buffer[module][2*y0+1]|=0x40; break;
                    case 10:Module_Green1Buffer[module][2*y0+1]|=0x20; break;
                    case 11:Module_Green1Buffer[module][2*y0+1]|=0x10; break;
                    case 12:Module_Green1Buffer[module][2*y0+1]|=0x08; break;
                    case 13:Module_Green1Buffer[module][2*y0+1]|=0x04; break;
                    case 14:Module_Green1Buffer[module][2*y0+1]|=0x02; break;
                    case 15:Module_Green1Buffer[module][2*y0+1]|=0x01; break;
                    default:break;
            }
                else
                switch(x0)
            {
                case 0 :Module_Green2Buffer[module][2*m]  |=0x80; break;
                    case 1 :Module_Green2Buffer[module][2*m]  |=0x40; break;
                    case 2 :Module_Green2Buffer[module][2*m]  |=0x20; break;
                    case 3 :Module_Green2Buffer[module][2*m]  |=0x10; break;
                    case 4 :Module_Green2Buffer[module][2*m]  |=0x08; break;
                    case 5 :Module_Green2Buffer[module][2*m]  |=0x04; break;
                    case 6 :Module_Green2Buffer[module][2*m]  |=0x02; break;
                    case 7 :Module_Green2Buffer[module][2*m]  |=0x01; break;

                    case 8 :Module_Green2Buffer[module][2*m+1]|=0x80; break;
                    case 9 :Module_Green2Buffer[module][2*m+1]|=0x40; break;
                    case 10:Module_Green2Buffer[module][2*m+1]|=0x20; break;
                    case 11:Module_Green2Buffer[module][2*m+1]|=0x10; break;
                    case 12:Module_Green2Buffer[module][2*m+1]|=0x08; break;
                    case 13:Module_Green2Buffer[module][2*m+1]|=0x04; break;
                    case 14:Module_Green2Buffer[module][2*m+1]|=0x02; break;
                    case 15:Module_Green2Buffer[module][2*m+1]|=0x01; break;
                    default:break;
            }
    }
        else if(color==ClearGreen)
        {
            if(y0<16)
                switch(x0)
            {
                case 0 :Module_Green1Buffer[module][2*y0]  &=~0x80; break;
                    case 1 :Module_Green1Buffer[module][2*y0]  &=~0x40; break;
                    case 2 :Module_Green1Buffer[module][2*y0]  &=~0x20; break;
                    case 3 :Module_Green1Buffer[module][2*y0]  &=~0x10; break;
                    case 4 :Module_Green1Buffer[module][2*y0]  &=~0x08; break;
                    case 5 :Module_Green1Buffer[module][2*y0]  &=~0x04; break;
                    case 6 :Module_Green1Buffer[module][2*y0]  &=~0x02; break;
                    case 7 :Module_Green1Buffer[module][2*y0]  &=~0x01; break;

                    case 8 :Module_Green1Buffer[module][2*y0+1]&=~0x80; break;
                    case 9 :Module_Green1Buffer[module][2*y0+1]&=~0x40; break;
                    case 10:Module_Green1Buffer[module][2*y0+1]&=~0x20; break;
                    case 11:Module_Green1Buffer[module][2*y0+1]&=~0x10; break;
                    case 12:Module_Green1Buffer[module][2*y0+1]&=~0x08; break;
                    case 13:Module_Green1Buffer[module][2*y0+1]&=~0x04; break;
                    case 14:Module_Green1Buffer[module][2*y0+1]&=~0x02; break;
                    case 15:Module_Green1Buffer[module][2*y0+1]&=~0x01; break;
                    default:break;
            }
                else
                switch(x0)
            {
                case 0 :Module_Green2Buffer[module][2*m]  &=~0x80; break;
                    case 1 :Module_Green2Buffer[module][2*m]  &=~0x40; break;
                    case 2 :Module_Green2Buffer[module][2*m]  &=~0x20; break;
                    case 3 :Module_Green2Buffer[module][2*m]  &=~0x10; break;
                    case 4 :Module_Green2Buffer[module][2*m]  &=~0x08; break;
                    case 5 :Module_Green2Buffer[module][2*m]  &=~0x04; break;
                    case 6 :Module_Green2Buffer[module][2*m]  &=~0x02; break;
                    case 7 :Module_Green2Buffer[module][2*m]  &=~0x01; break;

                    case 8 :Module_Green2Buffer[module][2*m+1]&=~0x80; break;
                    case 9 :Module_Green2Buffer[module][2*m+1]&=~0x40; break;
                    case 10:Module_Green2Buffer[module][2*m+1]&=~0x20; break;
                    case 11:Module_Green2Buffer[module][2*m+1]&=~0x10; break;
                    case 12:Module_Green2Buffer[module][2*m+1]&=~0x08; break;
                    case 13:Module_Green2Buffer[module][2*m+1]&=~0x04; break;
                    case 14:Module_Green2Buffer[module][2*m+1]&=~0x02; break;
                    case 15:Module_Green2Buffer[module][2*m+1]&=~0x01; break;
                    default:break;
            }
    }
       
        if(color==Yellor) //红绿混合即为黄
        {
            if(y0<16)
                switch(x0)
            {
                case 0 :Module_Red1Buffer[module][2*y0]    |=0x80;
                                        Module_Green1Buffer[module][2*y0]  |=0x80;
                                break;
                    case 1 :Module_Red1Buffer[module][2*y0]    |=0x40;
                                Module_Green1Buffer[module][2*y0]  |=0x40;
                                break;
                    case 2 :Module_Red1Buffer[module][2*y0]    |=0x20;
                                Module_Green1Buffer[module][2*y0]  |=0x20;
                                        break;
                    case 3 :Module_Red1Buffer[module][2*y0]    |=0x10;
                                Module_Green1Buffer[module][2*y0]  |=0x10;
                                break;
                    case 4 :Module_Red1Buffer[module][2*y0]    |=0x08;
                                Module_Green1Buffer[module][2*y0]  |=0x08;
                                        break;
                    case 5 :Module_Red1Buffer[module][2*y0]    |=0x04;
                                Module_Green1Buffer[module][2*y0]  |=0x04;
                                        break;
                    case 6 :Module_Red1Buffer[module][2*y0]    |=0x02;
                                Module_Green1Buffer[module][2*y0]  |=0x02;
                                        break;
                    case 7 :Module_Red1Buffer[module][2*y0]    |=0x01;
                                Module_Green1Buffer[module][2*y0]  |=0x01;
                                        break;
                    
                        case 8 :Module_Red1Buffer[module][2*y0+1]  |=0x80;
                                Module_Green1Buffer[module][2*y0+1]|=0x80;
                                        break;
                    case 9 :Module_Red1Buffer[module][2*y0+1]  |=0x40;
                                Module_Green1Buffer[module][2*y0+1]|=0x40;
                                        break;
                    case 10:Module_Red1Buffer[module][2*y0+1]  |=0x20;
                                Module_Green1Buffer[module][2*y0+1]|=0x20;
                                        break;
                    case 11:Module_Red1Buffer[module][2*y0+1]  |=0x10;
                                Module_Green1Buffer[module][2*y0+1]|=0x10;
                                        break;
                    case 12:Module_Red1Buffer[module][2*y0+1]  |=0x08;
                                Module_Green1Buffer[module][2*y0+1]|=0x08;
                                        break;
                    case 13:Module_Red1Buffer[module][2*y0+1]  |=0x04;
                                Module_Green1Buffer[module][2*y0+1]|=0x04;
                                        break;
                    case 14:Module_Red1Buffer[module][2*y0+1]  |=0x02;
                                Module_Green1Buffer[module][2*y0+1]|=0x02;
                                        break;
                    case 15:Module_Red1Buffer[module][2*y0+1]  |=0x01;
                                Module_Green1Buffer[module][2*y0+1]|=0x01;
                                        break;
                    default:break;
            }
                else
                switch(x0)
            {
                case 0 :Module_Red2Buffer[module][2*m]    |=0x80;
                                        Module_Green2Buffer[module][2*m]  |=0x80;
                                break;
                    case 1 :Module_Red2Buffer[module][2*m]    |=0x40;
                                Module_Green2Buffer[module][2*m]  |=0x40;
                                break;
                    case 2 :Module_Red2Buffer[module][2*m]    |=0x20;
                                Module_Green2Buffer[module][2*m]  |=0x20;
                                        break;
                    case 3 :Module_Red2Buffer[module][2*m]    |=0x10;
                                Module_Green2Buffer[module][2*m]  |=0x10;
                                break;
                    case 4 :Module_Red2Buffer[module][2*m]    |=0x08;
                                Module_Green2Buffer[module][2*m]  |=0x08;
                                        break;
                    case 5 :Module_Red2Buffer[module][2*m]    |=0x04;
                                Module_Green2Buffer[module][2*m]  |=0x04;
                                        break;
                    case 6 :Module_Red2Buffer[module][2*m]    |=0x02;
                                Module_Green2Buffer[module][2*m]  |=0x02;
                                        break;
                    case 7 :Module_Red2Buffer[module][2*m]    |=0x01;
                                Module_Green2Buffer[module][2*m]  |=0x01;
                                        break;
                    
                        case 8 :Module_Red2Buffer[module][2*m+1]  |=0x80;
                                Module_Green2Buffer[module][2*m+1]|=0x80;
                                        break;
                    case 9 :Module_Red2Buffer[module][2*m+1]  |=0x40;
                                Module_Green2Buffer[module][2*m+1]|=0x40;
                                        break;
                    case 10:Module_Red2Buffer[module][2*m+1]  |=0x20;
                                Module_Green2Buffer[module][2*m+1]|=0x20;
                                        break;
                    case 11:Module_Red2Buffer[module][2*m+1]  |=0x10;
                                Module_Green2Buffer[module][2*m+1]|=0x10;
                                        break;
                    case 12:Module_Red2Buffer[module][2*m+1]  |=0x08;
                                Module_Green2Buffer[module][2*m+1]|=0x08;
                                        break;
                    case 13:Module_Red2Buffer[module][2*m+1]  |=0x04;
                                Module_Green2Buffer[module][2*m+1]|=0x04;
                                        break;
                    case 14:Module_Red2Buffer[module][2*m+1]  |=0x02;
                                Module_Green2Buffer[module][2*m+1]|=0x02;
                                        break;
                    case 15:Module_Red2Buffer[module][2*m+1]  |=0x01;
                                Module_Green2Buffer[module][2*m+1]|=0x01;
                                        break;
                    default:break;
            }
    }       
}

void Scan_IndoorModule(void)
{
    static INT8U Line=0;
        INT8S module;

           Line++;
        Line=Line%16;

        IndoorLE_low();
        IndoorHC138_disable();
        hc138scan(Line);
        for(module=InMODULE_NUM-1;module>=0;module--)
        {
                IndoorShift(LCD_Red1Buffer[module][2*Line]  ,LCD_Red2Buffer[module][2*Line]  ,LCD_Green1Buffer[module][2*Line]  ,LCD_Green2Buffer[module][2*Line]  );
            IndoorShift(LCD_Red1Buffer[module][2*Line+1],LCD_Red2Buffer[module][2*Line+1],LCD_Green1Buffer[module][2*Line+1],LCD_Green2Buffer[module][2*Line+1]);
        }
        IndoorLE_high();
        IndoorHC138_enable();
}


这个是用 两个LED 模组级联的(双色LED模组 64×32)

出0入0汤圆

 楼主| 发表于 2011-1-18 08:35:43 | 显示全部楼层
不要纸上谈兵的DD,上代码解决最后的战斗。

这个不是LCD,LCD一般有驱动芯片的,这个是LED点阵,驱动就是MCU自己。

出0入0汤圆

发表于 2011-1-18 08:35:44 | 显示全部楼层
以上程序经过实际验证过的  绝对可行  用在室内LED模组驱动上面  用STM32单片机  非常合适

出0入0汤圆

发表于 2011-1-18 08:36:58 | 显示全部楼层
四年前的三本,3个小时我也许做不错来,做出来的也会闪烁,拖尾。我们班能做出来的也能最多几个。

出0入4汤圆

发表于 2011-1-18 08:44:40 | 显示全部楼层
这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。

出0入0汤圆

发表于 2011-1-18 08:44:58 | 显示全部楼层
室外LED模组打点函数驱动稍微复杂一点:

/*--------------File Info-------------------------------------------------------
** 文   件   名:  OutdoorModule.c
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  户外LED模组驱动函数                       
**------------------------------------------------------------------------------
** Created   by:  JJX                 
** Created date:         
*******************************************************************************/
#include "config.h"
#include "GUI.h"

//outdoor
INT8U GUI_RedBuffer[OutMODULE_NUM][32];       
INT8U GUI_GreenBuffer[OutMODULE_NUM][32];

INT8U Module_RedBuffer[OutMODULE_NUM][32];
INT8U Module_GreenBuffer[OutMODULE_NUM][32];

//定时器调用
INT8U LCD_RedBuffer[OutMODULE_NUM][32];
INT8U LCD_GreenBuffer[OutMODULE_NUM][32];

void OutdoorShift(INT8U red,INT8U green)
{
    INT8U i;
                            
    for(i=8;i>0;i--)
    {
        OutdoorCLK_low();
                    
        if((red&0x80)!=0)
                    OutdoorR_data_high();         
        else
                    OutdoorR_data_low();

                if((green&0x80)!=0)
                    OutdoorG_data_high();         
        else
                    OutdoorG_data_low();
                       
        OutdoorCLK_high();
                                        
        red=red<<1;
                green=green<<1;         
    }                  
}

void Convert(INT8U module)
{
    //Red
        Module_RedBuffer[module][0] = GUI_RedBuffer[module][24];
        Module_RedBuffer[module][1] = GUI_RedBuffer[module][16];   
    Module_RedBuffer[module][2] = GUI_RedBuffer[module][8];
        Module_RedBuffer[module][3] = GUI_RedBuffer[module][0];
        Module_RedBuffer[module][4] = GUI_RedBuffer[module][25];
        Module_RedBuffer[module][5] = GUI_RedBuffer[module][17];
        Module_RedBuffer[module][6] = GUI_RedBuffer[module][9];
        Module_RedBuffer[module][7] = GUI_RedBuffer[module][1];

        Module_RedBuffer[module][8] = GUI_RedBuffer[module][26];
        Module_RedBuffer[module][9] = GUI_RedBuffer[module][18];   
    Module_RedBuffer[module][10]= GUI_RedBuffer[module][10];
        Module_RedBuffer[module][11]= GUI_RedBuffer[module][2];
        Module_RedBuffer[module][12]= GUI_RedBuffer[module][27];
        Module_RedBuffer[module][13]= GUI_RedBuffer[module][19];
        Module_RedBuffer[module][14]= GUI_RedBuffer[module][11];
        Module_RedBuffer[module][15]= GUI_RedBuffer[module][3];

        Module_RedBuffer[module][16]= GUI_RedBuffer[module][28];
        Module_RedBuffer[module][17]= GUI_RedBuffer[module][20];   
    Module_RedBuffer[module][18]= GUI_RedBuffer[module][12];
        Module_RedBuffer[module][19]= GUI_RedBuffer[module][4];
        Module_RedBuffer[module][20]= GUI_RedBuffer[module][29];
        Module_RedBuffer[module][21]= GUI_RedBuffer[module][21];
        Module_RedBuffer[module][22]= GUI_RedBuffer[module][13];
        Module_RedBuffer[module][23]= GUI_RedBuffer[module][5];

        Module_RedBuffer[module][24]= GUI_RedBuffer[module][30];
        Module_RedBuffer[module][25]= GUI_RedBuffer[module][22];   
    Module_RedBuffer[module][26]= GUI_RedBuffer[module][14];
        Module_RedBuffer[module][27]= GUI_RedBuffer[module][6];
        Module_RedBuffer[module][28]= GUI_RedBuffer[module][31];
        Module_RedBuffer[module][29]= GUI_RedBuffer[module][23];
        Module_RedBuffer[module][30]= GUI_RedBuffer[module][15];
        Module_RedBuffer[module][31]= GUI_RedBuffer[module][7];

        //Green
        Module_GreenBuffer[module][0] = GUI_GreenBuffer[module][24];
        Module_GreenBuffer[module][1] = GUI_GreenBuffer[module][16];   
    Module_GreenBuffer[module][2] = GUI_GreenBuffer[module][8];
        Module_GreenBuffer[module][3] = GUI_GreenBuffer[module][0];
        Module_GreenBuffer[module][4] = GUI_GreenBuffer[module][25];
        Module_GreenBuffer[module][5] = GUI_GreenBuffer[module][17];
        Module_GreenBuffer[module][6] = GUI_GreenBuffer[module][9];
        Module_GreenBuffer[module][7] = GUI_GreenBuffer[module][1];

        Module_GreenBuffer[module][8] = GUI_GreenBuffer[module][26];
        Module_GreenBuffer[module][9] = GUI_GreenBuffer[module][18];   
    Module_GreenBuffer[module][10]= GUI_GreenBuffer[module][10];
        Module_GreenBuffer[module][11]= GUI_GreenBuffer[module][2];
        Module_GreenBuffer[module][12]= GUI_GreenBuffer[module][27];
        Module_GreenBuffer[module][13]= GUI_GreenBuffer[module][19];
        Module_GreenBuffer[module][14]= GUI_GreenBuffer[module][11];
        Module_GreenBuffer[module][15]= GUI_GreenBuffer[module][3];

        Module_GreenBuffer[module][16]= GUI_GreenBuffer[module][28];
        Module_GreenBuffer[module][17]= GUI_GreenBuffer[module][20];   
    Module_GreenBuffer[module][18]= GUI_GreenBuffer[module][12];
        Module_GreenBuffer[module][19]= GUI_GreenBuffer[module][4];
        Module_GreenBuffer[module][20]= GUI_GreenBuffer[module][29];
        Module_GreenBuffer[module][21]= GUI_GreenBuffer[module][21];
        Module_GreenBuffer[module][22]= GUI_GreenBuffer[module][13];
        Module_GreenBuffer[module][23]= GUI_GreenBuffer[module][5];

        Module_GreenBuffer[module][24]= GUI_GreenBuffer[module][30];
        Module_GreenBuffer[module][25]= GUI_GreenBuffer[module][22];   
    Module_GreenBuffer[module][26]= GUI_GreenBuffer[module][14];
        Module_GreenBuffer[module][27]= GUI_GreenBuffer[module][6];
        Module_GreenBuffer[module][28]= GUI_GreenBuffer[module][31];
        Module_GreenBuffer[module][29]= GUI_GreenBuffer[module][23];
        Module_GreenBuffer[module][30]= GUI_GreenBuffer[module][15];
        Module_GreenBuffer[module][31]= GUI_GreenBuffer[module][7];
}

//本函数实现与驱动有关,要理解程序请参考驱动电路图
void Outdoor_DrawPoint(INT16S x0,INT16S y0,INT8U color)
{
    INT8U module;
   
        if( (x0<0)||(x0>=GUI_XWORD*16) )     return;
        if( (y0<0)||(y0>=OutdoorLCD_YSIZE) ) return;

        if( GUI_XWORD>OutdoorLCD_XSIZE/16 )  return;
        //if(GUI_YWORD>OutdoorLCD_YSIZE/16) return;

        module=GUI_XWORD-1-(x0/16);

        y0=y0%16;
        x0=x0%16;

        if(color==Red)
        switch(x0)
        {
            case 0 :GUI_RedBuffer[module][2*y0]  |=0x80; break;
                case 1 :GUI_RedBuffer[module][2*y0]  |=0x40; break;
                case 2 :GUI_RedBuffer[module][2*y0]  |=0x20; break;
                case 3 :GUI_RedBuffer[module][2*y0]  |=0x10; break;
                case 4 :GUI_RedBuffer[module][2*y0]  |=0x08; break;
                case 5 :GUI_RedBuffer[module][2*y0]  |=0x04; break;
                case 6 :GUI_RedBuffer[module][2*y0]  |=0x02; break;
                case 7 :GUI_RedBuffer[module][2*y0]  |=0x01; break;

                case 8 :GUI_RedBuffer[module][2*y0+1]|=0x80; break;
                case 9 :GUI_RedBuffer[module][2*y0+1]|=0x40; break;
                case 10:GUI_RedBuffer[module][2*y0+1]|=0x20; break;
                case 11:GUI_RedBuffer[module][2*y0+1]|=0x10; break;
                case 12:GUI_RedBuffer[module][2*y0+1]|=0x08; break;
                case 13:GUI_RedBuffer[module][2*y0+1]|=0x04; break;
                case 14:GUI_RedBuffer[module][2*y0+1]|=0x02; break;
                case 15:GUI_RedBuffer[module][2*y0+1]|=0x01; break;
                default:break;
        }
        else if(color==ClearRed)
        switch(x0)
        {
            case 0 :GUI_RedBuffer[module][2*y0]  &=~0x80; break;
                case 1 :GUI_RedBuffer[module][2*y0]  &=~0x40; break;
                case 2 :GUI_RedBuffer[module][2*y0]  &=~0x20; break;
                case 3 :GUI_RedBuffer[module][2*y0]  &=~0x10; break;
                case 4 :GUI_RedBuffer[module][2*y0]  &=~0x08; break;
                case 5 :GUI_RedBuffer[module][2*y0]  &=~0x04; break;
                case 6 :GUI_RedBuffer[module][2*y0]  &=~0x02; break;
                case 7 :GUI_RedBuffer[module][2*y0]  &=~0x01; break;

                case 8 :GUI_RedBuffer[module][2*y0+1]&=~0x80; break;
                case 9 :GUI_RedBuffer[module][2*y0+1]&=~0x40; break;
                case 10:GUI_RedBuffer[module][2*y0+1]&=~0x20; break;
                case 11:GUI_RedBuffer[module][2*y0+1]&=~0x10; break;
                case 12:GUI_RedBuffer[module][2*y0+1]&=~0x08; break;
                case 13:GUI_RedBuffer[module][2*y0+1]&=~0x04; break;
                case 14:GUI_RedBuffer[module][2*y0+1]&=~0x02; break;
                case 15:GUI_RedBuffer[module][2*y0+1]&=~0x01; break;
                default:break;
        }
       
        else if(color==Green)
        switch(x0)
        {
            case 0 :GUI_GreenBuffer[module][2*y0]  |=0x80; break;
                case 1 :GUI_GreenBuffer[module][2*y0]  |=0x40; break;
                case 2 :GUI_GreenBuffer[module][2*y0]  |=0x20; break;
                case 3 :GUI_GreenBuffer[module][2*y0]  |=0x10; break;
                case 4 :GUI_GreenBuffer[module][2*y0]  |=0x08; break;
                case 5 :GUI_GreenBuffer[module][2*y0]  |=0x04; break;
                case 6 :GUI_GreenBuffer[module][2*y0]  |=0x02; break;
                case 7 :GUI_GreenBuffer[module][2*y0]  |=0x01; break;

                case 8 :GUI_GreenBuffer[module][2*y0+1]|=0x80; break;
                case 9 :GUI_GreenBuffer[module][2*y0+1]|=0x40; break;
                case 10:GUI_GreenBuffer[module][2*y0+1]|=0x20; break;
                case 11:GUI_GreenBuffer[module][2*y0+1]|=0x10; break;
                case 12:GUI_GreenBuffer[module][2*y0+1]|=0x08; break;
                case 13:GUI_GreenBuffer[module][2*y0+1]|=0x04; break;
                case 14:GUI_GreenBuffer[module][2*y0+1]|=0x02; break;
                case 15:GUI_GreenBuffer[module][2*y0+1]|=0x01; break;
                default:break;
        }
        else if(color==ClearGreen)
        switch(x0)
        {
            case 0 :GUI_GreenBuffer[module][2*y0]  &=~0x80; break;
                case 1 :GUI_GreenBuffer[module][2*y0]  &=~0x40; break;
                case 2 :GUI_GreenBuffer[module][2*y0]  &=~0x20; break;
                case 3 :GUI_GreenBuffer[module][2*y0]  &=~0x10; break;
                case 4 :GUI_GreenBuffer[module][2*y0]  &=~0x08; break;
                case 5 :GUI_GreenBuffer[module][2*y0]  &=~0x04; break;
                case 6 :GUI_GreenBuffer[module][2*y0]  &=~0x02; break;
                case 7 :GUI_GreenBuffer[module][2*y0]  &=~0x01; break;

                case 8 :GUI_GreenBuffer[module][2*y0+1]&=~0x80; break;
                case 9 :GUI_GreenBuffer[module][2*y0+1]&=~0x40; break;
                case 10:GUI_GreenBuffer[module][2*y0+1]&=~0x20; break;
                case 11:GUI_GreenBuffer[module][2*y0+1]&=~0x10; break;
                case 12:GUI_GreenBuffer[module][2*y0+1]&=~0x08; break;
                case 13:GUI_GreenBuffer[module][2*y0+1]&=~0x04; break;
                case 14:GUI_GreenBuffer[module][2*y0+1]&=~0x02; break;
                case 15:GUI_GreenBuffer[module][2*y0+1]&=~0x01; break;
                default:break;
        }
       
        else if(color==Yellor)//红绿混合即为黄
        switch(x0)
        {
            case 0 :GUI_RedBuffer[module][2*y0]    |=0x80;
                        GUI_GreenBuffer[module][2*y0]  |=0x80;
                                break;
                case 1 :GUI_RedBuffer[module][2*y0]    |=0x40;
                        GUI_GreenBuffer[module][2*y0]  |=0x40;
                                break;
                case 2 :GUI_RedBuffer[module][2*y0]    |=0x20;
                        GUI_GreenBuffer[module][2*y0]  |=0x20;
                                break;
                case 3 :GUI_RedBuffer[module][2*y0]    |=0x10;
                        GUI_GreenBuffer[module][2*y0]  |=0x10;
                                break;
                case 4 :GUI_RedBuffer[module][2*y0]    |=0x08;
                        GUI_GreenBuffer[module][2*y0]  |=0x08;
                                break;
                case 5 :GUI_RedBuffer[module][2*y0]    |=0x04;
                        GUI_GreenBuffer[module][2*y0]  |=0x04;
                                break;
                case 6 :GUI_RedBuffer[module][2*y0]    |=0x02;
                        GUI_GreenBuffer[module][2*y0]  |=0x02;
                                break;
                case 7 :GUI_RedBuffer[module][2*y0]    |=0x01;
                        GUI_GreenBuffer[module][2*y0]  |=0x01;
                                break;

                case 8 :GUI_RedBuffer[module][2*y0+1]  |=0x80;
                        GUI_GreenBuffer[module][2*y0+1]|=0x80;
                                break;
                case 9 :GUI_RedBuffer[module][2*y0+1]  |=0x40;
                        GUI_GreenBuffer[module][2*y0+1]|=0x40;
                                break;
                case 10:GUI_RedBuffer[module][2*y0+1]  |=0x20;
                        GUI_GreenBuffer[module][2*y0+1]|=0x20;
                                break;
                case 11:GUI_RedBuffer[module][2*y0+1]  |=0x10;
                        GUI_GreenBuffer[module][2*y0+1]|=0x10;
                                break;
                case 12:GUI_RedBuffer[module][2*y0+1]  |=0x08;
                        GUI_GreenBuffer[module][2*y0+1]|=0x08;
                                break;
                case 13:GUI_RedBuffer[module][2*y0+1]  |=0x04;
                        GUI_GreenBuffer[module][2*y0+1]|=0x04;
                                break;
                case 14:GUI_RedBuffer[module][2*y0+1]  |=0x02;
                        GUI_GreenBuffer[module][2*y0+1]|=0x02;
                                break;
                case 15:GUI_RedBuffer[module][2*y0+1]  |=0x01;
                        GUI_GreenBuffer[module][2*y0+1]|=0x01;
                                break;
                default:break;
        }
}

void Scan_OutdoorModule(void)
{
    INT8S i,module;
    static INT8U Step=0;
       
           Step++;
        Step=Step%4;

        if( Step==0 )
        {
                //扫描1,5,9,13行
                OutdoorHC138_disable();
                OutdoorLE_low();
                for(module=OutMODULE_NUM-1;module>=0;module--)
                {
                        for(i=0;i<4;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
                        for(i=4;i<8;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
            }
            OutdoorLE_high();
                OutdoorA0_low();
            OutdoorA1_low();
                OutdoorHC138_enable();
                OutdoorLE_low();
        }
        else if( Step==1 )
        {
                //扫描2,6,10,14行
                OutdoorHC138_disable();
                OutdoorLE_low();
                for(module=OutMODULE_NUM-1;module>=0;module--)
                {
                    for(i= 8;i<12;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
                        for(i=12;i<16;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
            }
            OutdoorLE_high();
            OutdoorA0_high();
            OutdoorA1_low();
                OutdoorHC138_enable();
                OutdoorLE_low();
        }       
        else if( Step==2 )
        {       
                //扫描3,7,11,15行
                OutdoorHC138_disable();
                OutdoorLE_low();
                for(module=OutMODULE_NUM-1;module>=0;module--)
                {
                    for(i=16;i<20;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
                        for(i=20;i<24;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
            }
            OutdoorLE_high();
            OutdoorA0_low();
            OutdoorA1_high();
                OutdoorHC138_enable();
                OutdoorLE_low();
        }
        else if( Step==3 )
        {
                //扫描4,8,12,16行
                OutdoorHC138_disable();
                OutdoorLE_low();
                for(module=OutMODULE_NUM-1;module>=0;module--)
                {
                    for(i=24;i<28;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
                        for(i=28;i<32;i++) OutdoorShift(LCD_RedBuffer[module],LCD_GreenBuffer[module]);
            }
            OutdoorLE_high();
            OutdoorA0_high();
            OutdoorA1_high();
                OutdoorHC138_enable();
                OutdoorLE_low();
        }
}

void Display_Time(INT8U color)
{
    struct tm time_now ;

        INT8S j,k;

        INT8U s[50];
        INT8U *year="年";
        INT8U *month="月";                                          
        INT8U *day="日";
        INT8U *hour="时";
        INT8U *minute="分";
        INT8U *weekday="星期";

        time_now = Time_GetCalendarTime();

        //年
        s[0]=time_now.tm_year/10%10+'0';
        s[1]=time_now.tm_year%10+'0';
        s[2]=year[0];
        s[3]=year[1];

        //月
        s[4]=(time_now.tm_mon+1)/10%10+'0';
        s[5]=(time_now.tm_mon+1)%10+'0';
        s[6]=month[0];
        s[7]=month[1];

        //日
        s[8]=time_now.tm_mday/10%10+'0';
        s[9]=time_now.tm_mday%10+'0';
        s[10]=day[0];
        s[11]=day[1];

        //时
        s[12]=time_now.tm_hour/10%10+'0';
        s[13]=time_now.tm_hour%10+'0';
        s[14]=hour[0];
        s[15]=hour[1];

        //分
        s[16]=time_now.tm_min/10%10+'0';
        s[17]=time_now.tm_min%10+'0';
        s[18]=minute[0];
        s[19]=minute[1];

        //星期
        //s[20]=weekday[time_now.tm_wday][0];
        //s[21]=weekday[time_now.tm_wday][1];
        //s[22]=weekday[time_now.tm_wday][2];
        //s[23]=weekday[time_now.tm_wday][3];
        //s[24]=weekday[time_now.tm_wday][4];
        //s[25]=weekday[time_now.tm_wday][5];
   
        s[20]=' ';
        s[21]='\0';
       
        for(k=0,j=2*OutMODULE_NUM;k<(OutMODULE_NUM-1)*16-8;k++)
        {
                j++;
                j=j%(OutMODULE_NUM*16);

                GUI_Clear();
                GUI_DispStringAt(s,(OutMODULE_NUM*16)-j,0,color);
                GUI_Write_Module();
                delay_ms(100);
        }
}
这样就在LED上模组显示  时间了

出0入0汤圆

发表于 2011-1-18 08:51:38 | 显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文   件   名:  IndoorModule.h
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:                         
**------------------------------------------------------------------------------
** Created   by:                 
** Created date:         
*******************************************************************************/
#ifndef __IndoorModule_h
#define __IndoorModule_h

#include "config.h"

#define InMODULE_NUM            8

#define IndoorLCD_XSIZE                ((INT16U)(16*InMODULE_NUM))
#define IndoorLCD_YSIZE                ((INT16U)(16*2))

#define IndoorHC138_disable()   GPIO_SetBits(GPIOC,GPIO_Pin_0)//最好改成 GPIOC->BSRR = GPIO_Pin_0  效率更高
#define IndoorHC138_enable()    GPIO_ResetBits(GPIOC,GPIO_Pin_0)

#define IndoorR1_high()         GPIO_SetBits(GPIOC,GPIO_Pin_1)
#define IndoorR1_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_1)

#define IndoorR2_high()         GPIO_SetBits(GPIOC,GPIO_Pin_2)
#define IndoorR2_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_2)

#define IndoorG1_high()         GPIO_SetBits(GPIOC,GPIO_Pin_3)
#define IndoorG1_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_3)

#define IndoorG2_high()         GPIO_SetBits(GPIOC,GPIO_Pin_4)
#define IndoorG2_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_4)

#define IndoorCLK_high()        GPIO_SetBits(GPIOC,GPIO_Pin_6)
#define IndoorCLK_low()         GPIO_ResetBits(GPIOC,GPIO_Pin_6)

#define IndoorLE_high()         GPIO_SetBits(GPIOC,GPIO_Pin_5)
#define IndoorLE_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_5)

#define IndoorLA_high()         GPIO_SetBits(GPIOC,GPIO_Pin_7)
#define IndoorLA_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_7)

#define IndoorLB_high()         GPIO_SetBits(GPIOC,GPIO_Pin_8)
#define IndoorLB_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_8)

#define IndoorLC_high()         GPIO_SetBits(GPIOC,GPIO_Pin_9)
#define IndoorLC_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_9)

#define IndoorLD_high()         GPIO_SetBits(GPIOC,GPIO_Pin_10)
#define IndoorLD_low()          GPIO_ResetBits(GPIOC,GPIO_Pin_10)

extern INT8U Module_Red1Buffer[InMODULE_NUM][32];
extern INT8U Module_Red2Buffer[InMODULE_NUM][32];
extern INT8U Module_Green1Buffer[InMODULE_NUM][32];
extern INT8U Module_Green2Buffer[InMODULE_NUM][32];

//定时器调用
extern INT8U LCD_Red1Buffer[InMODULE_NUM][32];
extern INT8U LCD_Red2Buffer[InMODULE_NUM][32];
extern INT8U LCD_Green1Buffer[InMODULE_NUM][32];
extern INT8U LCD_Green2Buffer[InMODULE_NUM][32];

void IndoorShift(INT8U red1,INT8U red2,INT8U green1,INT8U green2);
void Indoor_DrawPoint(INT16S x0,INT16S y0,INT8U color);
void Scan_IndoorModule(void);

#endif

出0入0汤圆

发表于 2011-1-18 08:52:04 | 显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文   件   名:  OutdoorModule.h
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  测试                       
**------------------------------------------------------------------------------
** Created   by:JJX       
** Created date:         
*******************************************************************************/
#ifndef __OutdoorModule_h
#define __OutdoorModule_h

#include "config.h"

#define OutMODULE_NUM            2

#define OutdoorLCD_XSIZE             ((INT16U)(16*OutMODULE_NUM))
#define OutdoorLCD_YSIZE             ((INT16U)(16*1))

#define OutdoorHC138_disable()   GPIO_SetBits(GPIOB,GPIO_Pin_9)
#define OutdoorHC138_enable()    GPIO_ResetBits(GPIOB,GPIO_Pin_9)

#define OutdoorA0_high()         GPIO_SetBits(GPIOB,GPIO_Pin_10)
#define OutdoorA0_low()          GPIO_ResetBits(GPIOB,GPIO_Pin_10)

#define OutdoorA1_high()         GPIO_SetBits(GPIOB,GPIO_Pin_11)
#define OutdoorA1_low()          GPIO_ResetBits(GPIOB,GPIO_Pin_11)

#define OutdoorCLK_high()        GPIO_SetBits(GPIOB,GPIO_Pin_12)
#define OutdoorCLK_low()         GPIO_ResetBits(GPIOB,GPIO_Pin_12)

#define OutdoorLE_high()         GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define OutdoorLE_low()          GPIO_ResetBits(GPIOB,GPIO_Pin_13)

#define OutdoorR_data_high()     GPIO_SetBits(GPIOB,GPIO_Pin_14)
#define OutdoorR_data_low()      GPIO_ResetBits(GPIOB,GPIO_Pin_14)

#define OutdoorG_data_high()     GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define OutdoorG_data_low()      GPIO_ResetBits(GPIOB,GPIO_Pin_15)

extern INT8U GUI_RedBuffer[OutMODULE_NUM][32];
extern INT8U GUI_GreenBuffer[OutMODULE_NUM][32];

extern INT8U Module_RedBuffer[OutMODULE_NUM][32];
extern INT8U Module_GreenBuffer[OutMODULE_NUM][32];
//定时器调用
extern INT8U LCD_RedBuffer[OutMODULE_NUM][32];
extern INT8U LCD_GreenBuffer[OutMODULE_NUM][32];

void OutdoorShift(INT8U red,INT8U green);
void Convert(INT8U module);

void Outdoor_DrawPoint(INT16S x0,INT16S y0,INT8U color);

//定时器调用
void Scan_OutdoorModule(void);
//void Display_Time(INT8U color);

#endif

出0入0汤圆

发表于 2011-1-18 08:54:30 | 显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文   件   名:  GUI.c
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  
**------------------------------------------------------------------------------
** 创   建   者:  JJX
** 日        期:  2009.05.16
*******************************************************************************/
#include "config.h"
#include "GUI.h"
#include "GBK.h"

INT8U GUIEnglishFont = En_8x16;     //默认字体
INT8U Char_XSIZE= 8;    //英文字体X宽度 不能大于8
INT8U Char_YSIZE= 16;   //英文字体Y宽度 不能大于16

INT8U GUIChineseFont= Chinese_16x16;//默认字体
INT8U Chinese_XSIZE= 16;//中文字体x宽度         
INT8U Chinese_YSIZE= 16;//中文字体y宽度

INT8U GUI_XWORD=LCD_XSIZE/16;
INT8U GUI_YWORD=LCD_YSIZE/16;

void GUI_Init(void)
{
    GUI_Clear();
     
    GUIEnglishFont = En_8x16;
    Char_XSIZE = En_8x16_XSIZE;
    Char_YSIZE = En_8x16_YSIZE;
   
    GUIChineseFont=Chinese_16x16;
    Chinese_XSIZE=Chinese_16x16_XSIZE;//中文字体x宽度         
    Chinese_YSIZE=Chinese_16x16_YSIZE;//中文字体y宽度  
}

void GUI_Clear(void)
{
    INT8U i,module;
       
        for(module=0;module<OutMODULE_NUM;module++)
        for(i=0;i<32;i++)
        {
        //Outdoor
                Module_RedBuffer[module]=0x00;
                Module_GreenBuffer[module]=0x00;
                GUI_RedBuffer[module]=0x00;
                GUI_GreenBuffer[module]=0x00;       
        }

        for(module=0;module<InMODULE_NUM;module++)
        for(i=0;i<32;i++)
        {
                //Indoor
                Module_Red1Buffer[module]=0x00;
                Module_Red2Buffer[module]=0x00;
                Module_Green1Buffer[module]=0x00;
                Module_Green2Buffer[module]=0x00;       
        }
}

/**************************************************************************************
* 名    称: GUI_Point()
* 功    能:在指定位置上画点。
* 参    数:x                指定点所在列的位置
*          y                指定点所在行的位置
*          color        显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 返 回 值:返回值为1时表示操作成功,为0时表示操作失败。
**************************************************************************************/
void GUI_Point(INT16S x0, INT16S y0, INT8U color)
{
    Outdoor_DrawPoint(x0,y0,color);
        Indoor_DrawPoint(x0,y0,color);
}

/**************************************************************************************
* 名    称: GUI_HLine()
* 功    能:画水平线。
* 参    数: x0                水平线起点所在列的位置
*           y0                水平线起点所在行的位置
*           x1      水平线终点所在列的位置
*           color        显示颜色
* 返 回 值:
**************************************************************************************/
void GUI_HLine(INT16S x0, INT16S y0, INT16S x1, INT8U color)
{  
    INT16S  i;
       
        // 对x0、x1大小进行排列,以便画图
    if(x0>x1)                                                
    {  
            i = x1;
        x1 = x0;
        x0 = i;
    }
         
        for(i=0;i<x1-x0;i++)
    {
                GUI_Point(x0+i,y0,color);       
        }
}
/**************************************************************************************
* 名    称:GUI_RLine()
* 功    能:画竖直线 根据硬件特点,实现加速。
* 参    数:x0                垂直线起点所在列的位置
*           y0                垂直线起点所在行的位置
*           y1      垂直线终点所在行的位置
*           color        显示颜色
* 返 回 值:
**************************************************************************************/
void GUI_RLine(INT16S x0, INT16S y0, INT16S y1, INT8U color)
{  
    INT16S  i;
       
        // 对y0、y1大小进行排列,以便画图
    if(y0>y1)                
    {  
            i = y1;
        y1 = y0;
        y0 = i;
    }
    for(i=0;i<y1-y0;i++)
    {
                GUI_Point(x0,y0+i,color);       
    }
}                  

/****************************************************************************
* 名称:GUI_Rectangle()
* 功能:画矩形。
* 入口参数: x0                矩形左上角的x坐标值
*           y0                矩形左上角的y坐标值
*           x1      矩形右下角的x坐标值
*           y1      矩形右下角的y坐标值
*           color        显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Rectangle(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color)
{  
    GUI_HLine(x0, y0, x1, color);
    GUI_HLine(x0, y1, x1, color);
    GUI_RLine(x0, y0, y1, color);
    GUI_RLine(x1, y0, y1, color);
}


/****************************************************************************
* 名称:GUI_Circle()
* 功能:指定圆心位置及半径,画圆。
* 入口参数: x0                圆心的x坐标值
*            y0                圆心的y坐标值
*            r      圆的半径
*            color        显示颜色
* 出口参数: 无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Circle(INT16S x0, INT16S y0, INT16S r, INT8U color)
{  
    INT16S  draw_x0, draw_y0;                // 刽图点坐标变量
    INT16S  draw_x1, draw_y1;       
    INT16S  draw_x2, draw_y2;       
    INT16S  draw_x3, draw_y3;       
    INT16S  draw_x4, draw_y4;       
    INT16S  draw_x5, draw_y5;       
    INT16S  draw_x6, draw_y6;       
    INT16S  draw_x7, draw_y7;       
    INT16S  xx, yy;                                        // 画圆控制变量

    INT16S  di;                                                // 决策变量
   
    /* 参数过滤 */
    if(0==r) return;
   
    /* 计算出8个特殊点(0、45、90、135、180、225、270度),进行显示 */
    draw_x0 = draw_x1 = x0;
    draw_y0 = draw_y1 = y0 + r;
    GUI_Point(draw_x0, draw_y0, color);        // 90度
       
    draw_x2 = draw_x3 = x0;
    draw_y2 = draw_y3 = y0 - r;
    if(draw_y2>=0) GUI_Point(draw_x2, draw_y2, color);                        // 270度
   
    draw_x4 = draw_x6 = x0 + r;
    draw_y4 = draw_y6 = y0;
    GUI_Point(draw_x4, draw_y4, color);        // 0度
   
    draw_x5 = draw_x7 = x0 - r;
    draw_y5 = draw_y7 = y0;
    if(draw_x5>=0) GUI_Point(draw_x5, draw_y5, color);                        // 180度   
    if(1==r) return;                                        // 若半径为1,则已圆画完
   
    /* 使用Bresenham法进行画圆 */
    di = 3 - 2*r;                                        // 初始化决策变量
   
    xx = 0;
    yy = r;       
    while(xx<yy)
    {  
        if(di<0)
            {  
                    di += 4*xx + 6;             
            }
            else
            {  
                    di += 4*(xx - yy) + 10;
          
                yy--;          
                    draw_y0--;
                    draw_y1--;
                    draw_y2++;
                    draw_y3++;
                    draw_x4--;
                    draw_x5++;
                    draw_x6--;
                    draw_x7++;                
            }
          
            xx++;   
            draw_x0++;
            draw_x1--;
            draw_x2++;
            draw_x3--;
            draw_y4++;
            draw_y5++;
            draw_y6--;
            draw_y7--;
               
             /* 要判断当前点是否在有效范围内 */
            if( draw_y0>=0 )       
            {  
                GUI_Point(draw_x0, draw_y0, color);
            }            
            if( (draw_x1>=0)&&(draw_y1>=0) )       
            {  
                GUI_Point(draw_x1, draw_y1, color);
            }
       
            GUI_Point(draw_x2, draw_y2, color);   
          
            if( draw_x3>=0)       
            {  
                GUI_Point(draw_x3, draw_y3, color);
            }

            if( draw_y4>=0 )       
            {  
                GUI_Point(draw_x4, draw_y4, color);
            }
            if( (draw_x5>=0)&&(draw_y5>=0) )       
            {  
                GUI_Point(draw_x5, draw_y5, color);
            }
       
            GUI_Point(draw_x6, draw_y6, color);
          
            if( draw_x7>=0 )       
            {  
                GUI_Point(draw_x7, draw_y7, color);
            }
    }
}

/****************************************************************************
* 名称:GUI_Ellipse()
* 功能:画正椭圆。给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点
*      的y轴坐标为y0、y1。
* 入口参数:x0                最左点的x坐标值
*           x1                最右点的x坐标值
*           y0                最上点的y坐标值
*           y1      最下点的y坐标值
*           color        显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Ellipse(INT16S x0,INT16S x1,INT16S y0,INT16S y1,INT8S color)
{
    INT16S draw_x0,draw_y0 ;
    // 刽图点坐标变量
    INT16S draw_x1,draw_y1 ;
    INT16S draw_x2,draw_y2 ;
    INT16S draw_x3,draw_y3 ;
    INT16S xx,yy ;
    // 画图控制变量
   
    INT16S center_x,center_y ;
    // 椭圆中心点坐标变量
    INT16S radius_x,radius_y ;
    // 椭圆的半径,x轴半径和y轴半径
    INT16S radius_xx,radius_yy ;
    // 半径乘平方值
    INT16S radius_xx2,radius_yy2 ;
    // 半径乘平方值的两倍
    INT16S di ;
    // 定义决策变量
   
    /* 参数过滤 */
    if((x0==x1)||(y0==y1))return ;
   
    /* 计算出椭圆中心点坐标 */
    center_x=(x0+x1)>>1 ;
    center_y=(y0+y1)>>1 ;
   
    /* 计算出椭圆的半径,x轴半径和y轴半径 */
    if(x0>x1)
    {
        radius_x=(x0-x1)>>1 ;
    }
    else
    {
        radius_x=(x1-x0)>>1 ;
    }
    if(y0>y1)
    {
        radius_y=(y0-y1)>>1 ;
    }
    else
    {
        radius_y=(y1-y0)>>1 ;
    }
   
    /* 计算半径平方值 */
    radius_xx=radius_x*radius_x ;
    radius_yy=radius_y*radius_y ;
   
    /* 计算半径平方值乘2值 */
    radius_xx2=radius_xx<<1 ;
    radius_yy2=radius_yy<<1 ;
   
    /* 初始化画图变量 */
    xx=0 ;
    yy=radius_y ;
   
    di=radius_yy2+radius_xx-radius_xx2*radius_y ;
    // 初始化决策变量
   
    /* 计算出椭圆y轴上的两个端点坐标,作为作图起点 */
    draw_x0=draw_x1=draw_x2=draw_x3=center_x ;
    draw_y0=draw_y1=center_y+radius_y ;
    draw_y2=draw_y3=center_y-radius_y ;
   
   
    GUI_Point(draw_x0,draw_y0,color);
    // 画y轴上的两个端点
    GUI_Point(draw_x2,draw_y2,color);
   
    while((radius_yy*xx)<(radius_xx*yy))
    {
        if(di<0)
        {
            di+=radius_yy2*(2*xx+3);
        }
        else
        {
            di+=radius_yy2*(2*xx+3)+4*radius_xx-4*radius_xx*yy ;
            
            yy--;
            draw_y0--;
            draw_y1--;
            draw_y2++;
            draw_y3++;
        }
        
        xx++;
        // x轴加1
        
        draw_x0++;
        draw_x1--;
        draw_x2++;
        draw_x3--;
        
        GUI_Point(draw_x0,draw_y0,color);
        GUI_Point(draw_x1,draw_y1,color);
        GUI_Point(draw_x2,draw_y2,color);
        GUI_Point(draw_x3,draw_y3,color);
    }
   
    di=radius_xx2*(yy-1)*(yy-1)+radius_yy2*xx*xx+radius_yy+radius_yy2*xx-radius_xx2*radius_yy ;
    while(yy>=0)
    {
        if(di<0)
        {
            di+=radius_xx2*3+4*radius_yy*xx+4*radius_yy-2*radius_xx2*yy ;
            
            xx++;
            // x轴加1
            draw_x0++;
            draw_x1--;
            draw_x2++;
            draw_x3--;
        }
        else
        {
            di+=radius_xx2*3-2*radius_xx2*yy ;
        }
        
        yy--;
        draw_y0--;
        draw_y1--;
        draw_y2++;
        draw_y3++;
        
        GUI_Point(draw_x0,draw_y0,color);
        GUI_Point(draw_x1,draw_y1,color);
        GUI_Point(draw_x2,draw_y2,color);
        GUI_Point(draw_x3,draw_y3,color);
    }
}







void GUI_Display_Data(INT8U data,INT16S x0,INT16S y0,INT8U color)
{     
    INT8U i;
       
    for(i=0;i<8;i++)
    {
        if( (data&(1<<i)) )
                {
                        Outdoor_DrawPoint(x0+7-i,y0,color);
                        Indoor_DrawPoint(x0+7-i,y0,color);
                }
    }     
}                

void GUI_Display_ASCII(INT8U Char,INT16S x0,INT16S y0,INT8U color)
{
    INT8U i;
    INT16U temp;
   
        //if(x0>=LCD_XSIZE) x0=x0%LCD_XSIZE;
        //if(y0>=LCD_YSIZE) y0=y0%LCD_YSIZE;
                               
    for(i=0;i<16;i++)
    {   
        temp=i+(INT16U)(Char-0x20)*16;   
                GUI_Display_Data(nAsciiDot[temp],x0,y0+i,color);
    }
}

void GUI_Display_Chinese(INT16U UniCode,INT16S x0,INT16S y0,INT8U color)
{
    INT16U CodeID;
    INT8U  i,ImgData;
    INT8U  temp;  
   
        INT8U ziku[32];
        //if(x0>=LCD_XSIZE) x0=x0%LCD_XSIZE;
        //if(y0>=LCD_YSIZE) y0=y0%LCD_YSIZE;       
       
    if( GUIChineseFont==Chinese_16x16 )
        {
                //在字库里搜索汉字
        for(CodeID=0; CodeID < HzNum; CodeID++)
        {
            // 找到 指定汉字的 Index 后, 跳出循环
            if( (GB_16[CodeID].Index[0]==UniCode/256) && (GB_16[CodeID].Index[1]==UniCode%256) )
                {
                break;
            }
        }
               
                //如果从Flash里面没有搜索到汉字,就从字库芯片里取数据。
            if( CodeID == HzNum )
        {
                    //未检索到的汉字,显示个"##"提示吧
            //GUI_Display_ASCII('#',x0,y0,color);
            //GUI_Display_ASCII('#',x0+Char_XSIZE,y0,color);
                       
                        Read_GT21L16S1W(UniCode,ziku); //从字库芯片GT21L16S1W读取数据到缓存ziku[];
               
                       temp=y0;
                for(i=0; i<Chinese_XSIZE*2; i+=2)
            {
                        ImgData = ziku;
                GUI_Display_Data(ImgData,x0,temp++,color);
            }
                temp=y0;
                for(i=1; i<Chinese_XSIZE*2; i+=2)
            {
                        ImgData = ziku;
                GUI_Display_Data(ImgData,x0+8,temp++,color);
            }
            return;
        }
                else
                {
            //----------------------------------
            temp=y0;
                for(i=0; i<Chinese_XSIZE*2; i+=2)
            {
                        ImgData = GB_16[CodeID].Msk;
                GUI_Display_Data(ImgData,x0,temp++,color);
            }
                temp=y0;
                for(i=1; i<Chinese_XSIZE*2; i+=2)
            {
                        ImgData = GB_16[CodeID].Msk;
                GUI_Display_Data(ImgData,x0+8,temp++,color);
            }  
                }
        }
       
        else if( GUIChineseFont==Chinese_12x12 )
        {
            //在字库里搜索汉字
        for(CodeID=0; CodeID < HzNum; CodeID++)
        {
            // 找到 指定汉字的 Index 后, 跳出循环
            if( (GB_12[CodeID].Index[0]==UniCode/256) && (GB_12[CodeID].Index[1]==UniCode%256) )
                {
                break;
            }
        }
            if( CodeID == HzNum )//未检索到的汉字,显示个"##"提示吧
        {
            GUI_Display_ASCII('#',x0,y0,color);
            GUI_Display_ASCII('#',x0+Char_XSIZE,y0,color);
            return;
        }

        //----------------------------------
        temp=y0;
            for(i=0; i<Chinese_XSIZE*2; i+=2)
        {
                    ImgData = GB_12[CodeID].Msk;
            GUI_Display_Data(ImgData,x0,temp++,color);
        }
            temp=y0;
            for(i=1; i<Chinese_XSIZE*2; i+=2)
        {
                    ImgData = GB_12[CodeID].Msk;
            GUI_Display_Data(ImgData,x0+8,temp++,color);
        }  
        }           
}

void GUI_DispStringAt(INT8U *s,INT16S x0,INT16S y0, INT8U color)
{
    INT8U i;  
    INT16U temp;
   
        //if(x0>LCD_XSIZE) x0=x0%LCD_XSIZE;
        //if(y0>LCD_YSIZE) y0=y0%LCD_YSIZE;       
       
    i = 0;
    while(s!='\0')
    {
        if (s < 0x80) //是ASCII
        {
             if(s == '\n')
             {
                 x0 = 0;
                 y0 += Char_YSIZE;
             }
             else
             {
                 if(x0 > GUI_XWORD*16-Char_XSIZE)
                 {
                     x0 = 0;
                     y0 += Char_YSIZE;
                 }
                                 GUI_Display_ASCII(s,x0, y0,color);      
                 x0 += Char_XSIZE;
             }
        }
        else //是中文
        {
            Char_YSIZE=En_8x16_YSIZE;//如果有中文,英文强制转换 8*16
            if(x0 > GUI_XWORD*16-Chinese_XSIZE)
            {
                x0 = 0;
                y0 += Chinese_YSIZE;
            }
            temp=(INT16U)(s)*256+s[i+1];
            GUI_Display_Chinese(temp,x0,y0,color);//中文
            x0 += Chinese_XSIZE;
                        i++;
       }
       i++;
    }
}

void GUI_CursorOn(INT16S x0, INT16S y0, INT8U color)
{
    INT8U i;
       
        for(i=0;i<8;i++)
        {
            //Outdoor
                Outdoor_DrawPoint(x0,y0+i,color);
                Outdoor_DrawPoint(x0+1,y0+i,color);
                //Indoor
                Indoor_DrawPoint(x0,y0+i,color);
                Indoor_DrawPoint(x0+1,y0+i,color);
        }  
}

// ---- 显示不带符号的整数  (数字 起始位置XY,显示长度) -----------------------------
void GUI_Display_Number(INT16U number, INT16S x0, INT16S y0, INT8U lenth, INT8U color)
{
    INT8U temp;

    x0 = ( x0 + lenth *En_8x16_XSIZE - En_8x16_XSIZE );

    for(; lenth>0; lenth--)
    {
        temp =(INT8U)(number%10) + '0';
        GUI_Display_ASCII(temp,x0,y0,color);
        
                x0 -= En_8x16_XSIZE;
                number = number / 10;
    }
}



/****************************************************************************
* 名称:GUI_RectangleFill()
* 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。
* 入口参数: x0                矩形左上角的x坐标值
*           y0                矩形左上角的y坐标值
*           x1      矩形右下角的x坐标值
*           y1      矩形右下角的y坐标值
*           color        填充颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_RectangleFill(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color)
{     
    INT16S x,y;
       
    for(x=x0;x<x1;x++)
    {
                for(y=y0;y<y1;y++)
                {
                    Outdoor_DrawPoint(x,y,color);
                        Indoor_DrawPoint(x,y,color);
                }
    }     
}


void GUI_Write_Module(void)
{
    INT8U i,module;

        //禁止中断
        TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 , DISABLE);
       
        //Outdoor
        for(module=0;module<OutMODULE_NUM;module++)
        {
            Convert(module);//GUI缓冲转化为模组缓冲数据
                for(i=0;i<32;i++)
                {
                        LCD_RedBuffer[module]  =Module_RedBuffer[module];
                        LCD_GreenBuffer[module]=Module_GreenBuffer[module];
                }
        }

        //Indoor
        for(module=0;module<InMODULE_NUM;module++)
        {
            for(i=0;i<32;i++)
                {
                        LCD_Red1Buffer[module]  =Module_Red1Buffer[module];
                        LCD_Red2Buffer[module]  =Module_Red2Buffer[module];
                        LCD_Green1Buffer[module]=Module_Green1Buffer[module];
                        LCD_Green2Buffer[module]=Module_Green2Buffer[module];
                }
        }

    TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 , ENABLE);
}

出0入0汤圆

发表于 2011-1-18 08:55:03 | 显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文   件   名:  GUI.h
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  
**------------------------------------------------------------------------------
** 创   建   者:  JJX
** 日        期:  2009.05.16
*******************************************************************************/
#ifndef __GUI_H
#define __GUI_H

#include "config.h"

#define LCD_XSIZE         ((INT16U)(16*InMODULE_NUM))
#define LCD_YSIZE         ((INT16U)(16*2))

//ASCII
#define Red          0x52
#define Green        0x47
#define Yellor       0x59

#define ClearRed     (~Red)
#define ClearGreen   (~Green)


//英文字体宽度定义
extern   INT8U   Char_XSIZE;
extern   INT8U   Char_YSIZE;

//英文的两种字体
#define  En_8x16                 0
#define  En_5x8                  1
//字体宽度定义
#define  En_8x16_XSIZE           8
#define  En_8x16_YSIZE           16
#define  En_5x8_XSIZE            5
#define  En_5x8_YSIZE            8

//中文字体宽度定义
extern   INT8U   Chinese_XSIZE;         
extern   INT8U   Chinese_YSIZE;         
//中文的两种字体
#define  Chinese_12x12           0
#define  Chinese_16x16           1
//中文字体宽度定义
#define  Chinese_12x12_XSIZE     12
#define  Chinese_12x12_YSIZE     12
#define  Chinese_16x16_XSIZE     16
#define  Chinese_16x16_YSIZE     16

extern   INT8U GUI_XWORD;
extern   INT8U GUI_YWORD;

void GUI_Init(void);                                                                                       
void GUI_Clear(void);

void GUI_Point(INT16S x0, INT16S y0, INT8U color);
void GUI_HLine(INT16S x0, INT16S y0, INT16S x1, INT8U color);
void GUI_RLine(INT16S x0, INT16S y0, INT16S y1, INT8U color);
void GUI_Rectangle(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color);
void GUI_RectangleFill(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color);
void GUI_Circle(INT16S x0, INT16S y0, INT16S r, INT8U color);
void GUI_Ellipse(INT16S x0, INT16S x1, INT16S y0, INT16S y1, INT8S color);

void GUI_Display_Data(INT8U data,INT16S x0,INT16S y0,INT8U color);
void GUI_Display_ASCII(INT8U Char, INT16S x0,INT16S y0,INT8U color);
void GUI_Display_Chinese(INT16U UniCode,INT16S x0,INT16S y0,INT8U color);
void GUI_DispStringAt(INT8U *s,INT16S x0,INT16S y0,INT8U color);

void GUI_CursorOn(INT16S x0, INT16S y0,INT8U color);

void GUI_Display_Number(INT16U number,INT16S x0,INT16S y0, INT8U lenth, INT8U color);

void GUI_Write_Module(void);

#endif

出0入0汤圆

 楼主| 发表于 2011-1-18 08:55:34 | 显示全部楼层
回复【55楼】jiangjx
以上程序经过实际验证过的  绝对可行  用在室内led模组驱动上面  用stm32单片机  非常合适
-----------------------------------------------------------------------

不漂亮,先考虑这个SWITCH如何优化吧,这样写实在没水平

switch(x0)
    {
        case 0 :Module_Green1Buffer[module][2*y0]  &=~0x80; break;
    case 1 :Module_Green1Buffer[module][2*y0]  &=~0x40; break;
    case 2 :Module_Green1Buffer[module][2*y0]  &=~0x20; break;
    case 3 :Module_Green1Buffer[module][2*y0]  &=~0x10; break;
    case 4 :Module_Green1Buffer[module][2*y0]  &=~0x08; break;
     case 5 :Module_Green1Buffer[module][2*y0]  &=~0x04; break;
     case 6 :Module_Green1Buffer[module][2*y0]  &=~0x02; break;
    case 7 :Module_Green1Buffer[module][2*y0]  &=~0x01; break;

    case 8 :Module_Green1Buffer[module][2*y0+1]&=~0x80; break;
    case 9 :Module_Green1Buffer[module][2*y0+1]&=~0x40; break;
    case 10:Module_Green1Buffer[module][2*y0+1]&=~0x20; break;
    case 11:Module_Green1Buffer[module][2*y0+1]&=~0x10; break;
    case 12:Module_Green1Buffer[module][2*y0+1]&=~0x08; break;
    case 13:Module_Green1Buffer[module][2*y0+1]&=~0x04; break;
    case 14:Module_Green1Buffer[module][2*y0+1]&=~0x02; break;
    case 15:Module_Green1Buffer[module][2*y0+1]&=~0x01; break;
    default:break;
    }



=======================================================================

改成

if (x0 < 8)
    Module_Green1Buffer[module][2*y0]  &= ~(0x80>>x0);
else  
    Module_Green1Buffer[module][2*y0+1] &= ~(0x80 >> (x0-8));

如何?

出0入0汤圆

发表于 2011-1-18 08:55:58 | 显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文   件   名:  GBK.h
** 最后修改日期:  2009.05.16
** 版        本:  V1.0
** 描        述:  
**------------------------------------------------------------------------------
** 创   建   者:  JJX
** 日        期:  2009.05.16
*******************************************************************************/
#ifndef __GBK_H
#define __GBK_H

#include "config.h"

#define HzNum             500

// ------------------  汉字字模的数据结构定义 ------------------------ //
typedef struct typFNT_GB16                 // 汉字字模数据结构
{
    INT8U Index[2];                        // 汉字内码索引
    INT8U Msk[32];                         // 点阵码数据
};
extern struct typFNT_GB16 const GB_16[];

// ------------------  汉字字模的数据结构定义 ------------------------ //
typedef struct typFNT_GB12                 // 汉字字模数据结构
{
    INT8U Index[2];                        // 汉字内码索引
    INT8U Msk[24];                         // 点阵码数据
};                                                                                  
extern struct typFNT_GB12 const GB_12[];

extern INT8U const nAsciiDot[];





//字库芯片GT21L16S1W
#define        GT21L16S1W_CS_HIGH()   GPIO_WriteBit(GPIOA, GPIO_Pin_3, 1);
#define        GT21L16S1W_CS_LOW()    GPIO_WriteBit(GPIOA, GPIO_Pin_3, 0);

#define        GT21L16S1W_HOLD_HIGH() GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
#define        GT21L16S1W_HOLD_LOW()  GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);

void Read_GT21L16S1W(INT16U UniCode,INT8U *s);


#endif

出0入0汤圆

发表于 2011-1-18 09:02:37 | 显示全部楼层
回复【63楼】machao
回复【55楼】jiangjx  
以上程序经过实际验证过的  绝对可行  用在室内led模组驱动上面  用stm32单片机  非常合适
-----------------------------------------------------------------------
不漂亮,先考虑这个switch如何优化吧,这样写实在没水平
switch(x0)  
    {  
        case 0 :module_green1buffer[module][2*y0]  &=~0x80; break;  
    case 1 :module_green1buffer[module][2*y0]  &=~0x40; break;  
    case 2 :module_green1buffer[module][2*y0]  &=~0x20; brea......
-----------------------------------------------------------------------

从执行效率(速度,对于这个应用速度是关键)来说,我觉得我那种写法更好  您这样写,效率更低  
这个地方用Case语句 可读性更好  执行效率也还不错 只是代码空间多了

出0入0汤圆

 楼主| 发表于 2011-1-18 09:06:30 | 显示全部楼层
回复【57楼】aleyn 煮茶村长
这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。
-----------------------------------------------------------------------

软件专业?我不看好他们。这个不是在PC上编程,堆起来出效果就行了。看看jiangjx的代码吧,恐怕就是软件专业的。效率体现在哪里?8位MCU,程序空间是有限的。

这个题目不是设计一个通用的8*8LED驱动,就完成一个简单的效果可以了。改为螺旋行转圈,恐怕95%的人不能在3个小时内完成。

出0入0汤圆

发表于 2011-1-18 09:13:44 | 显示全部楼层
回复【66楼】machao
回复【57楼】aleyn 煮茶村长
这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。  
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。
-----------------------------------------------------------------------
软件专业?我不看好他们。这个不是在pc上编程,堆起来出效果就行了。看看jiangjx的代码吧,恐怕就是软件专业的。效率体现在哪里?8位mcu,程序空间是有限的。
这个题目不是设计一个通用的8*8led驱动,就完成一个简单的效果可以了。改为螺旋行转圈,恐怕95%的人不能在3个小时内完成。

-----------------------------------------------------------------------

尽管您是大名鼎鼎的machao,但我不认同您的看法。
对于这个应用来说,执行效率是最重要的 可读性其次
你要看我的程序是用在 STM32上面的  代码空间256K  





if (x0 < 8)
    Module_Green1Buffer[module][2*y0]  &= ~(0x80>>x0);
else   
    Module_Green1Buffer[module][2*y0+1] &= ~(0x80 >> (x0-8));

如何?

强在哪里呢   执行效率更强?

出0入0汤圆

 楼主| 发表于 2011-1-18 09:14:08 | 显示全部楼层
回复【65楼】jiangjx
回复【63楼】machao  
回复【55楼】jiangjx   
以上程序经过实际验证过的  绝对可行  用在室内led模组驱动上面  用stm32单片机  非常合适  
-----------------------------------------------------------------------  
不漂亮,先考虑这个switch如何优化吧,这样写实在没水平  
switch(x0)   
    {   
        case 0 :module_green1buffer[module][2*y0]  &=~0x80; break;   
    case 1 :module_green1buffer[module][2*y0]  &=~0x40; break;   
    case 2 :module_green1buffer[module][......
-----------------------------------------------------------------------

不要不认帐,这样写执行比CASE快,代码也短,占用空间少。至于可读性并没有差多少。

你把两段代码的汇编找到,分析就可以了。

出0入0汤圆

发表于 2011-1-18 09:15:28 | 显示全部楼层
我说个思路不知行不行
这个东东 可以看成是8个数码管
做个显示缓冲区,在定时器里动态扫描。以显示稳定。这个和数码管一样,应该没什么问题
用查表或者算法 定时(软件定时标志)刷新缓冲区,这样就可以使灯转起来

键盘的处理可以参考马老师的书采用状态机的方法,通过修改软件定时变量实现显示时间改变。

反向旋转 只是查表和算法稍作修改既可

我们机电专业的学生估计全挂。

出0入0汤圆

发表于 2011-1-18 09:16:49 | 显示全部楼层
回复【67楼】jiangjx  
-----------------------------------------------------------------------

jiangjx要求“速度是关键”,恩。

考虑一下这段代码汇编会如何实现?
为了switch和case,标准编译器会生成一堆cmp / jmp类指令。如果支持Jump Table,并且指令集支持,那么会略好一点。
即,该程序会有很高的额外开销,如果case到比较靠后,额外开销会比计算开销大的多。

出0入0汤圆

发表于 2011-1-18 09:17:37 | 显示全部楼层
这里来挑战的都是学生吗?我想我大三的时候应该是可以在规定的时间搞定的。

不过。我是生物专业。

出0入0汤圆

发表于 2011-1-18 09:18:33 | 显示全部楼层
改成

if (x0 < 8)
    Module_Green1Buffer[module][2*y0]  &= ~(0x80>>x0);
else   
    Module_Green1Buffer[module][2*y0+1] &= ~(0x80 >> (x0-8));

如何?
//===========================================================
~(0x80>>x0);

这句用查表效率是不是能高一点

出0入0汤圆

发表于 2011-1-18 09:20:20 | 显示全部楼层
北大的同学终于有现身了,呵呵。

出0入0汤圆

发表于 2011-1-18 09:21:20 | 显示全部楼层
回复【68楼】machao
回复【65楼】jiangjx  
回复【63楼】machao   
回复【55楼】jiangjx   
以上程序经过实际验证过的  绝对可行  用在室内led模组驱动上面  用stm32单片机  非常合适   
-----------------------------------------------------------------------   
不漂亮,先考虑这个switch如何优化吧,这样写实在没水平   
switch(x0)   
    {   
        case 0 :module_green1buffer[module][2*y0]  &amp;=~0x80; break;   
    case 1 :module_green1buffer[module][2*y0]  &amp;=~0x40; break;   
    case 2 :mo......
-----------------------------------------------------------------------
有时间的话我一定验证一下  看看汇编代码

出0入0汤圆

发表于 2011-1-18 09:21:50 | 显示全部楼层
我觉得马老师说的有道理,看看现在学生的状态吧。
泡妞上网玩游戏,逃课挂科作弊,还有什么他们干不出来的?当然你们会说坏学生是少数。
周日跟朋友出去,听说了一个事情:
朋友公司招人,都是正经大学本科毕业的,单位大楼门口有三面国旗,左边是美国旗,中间是中国的,右边是加拿大的。
那位同学居然只认识中国国旗,同样的事情后来又发生在其他新人身上,这说明了什么?
个人素质差是一方面,可他们不是生来就差的,后面的就不说了。
另一方面,对于没见过的东西,如果不清楚原理,肯定三小时之内做不出来。
但学生们有多少人见过8*8LED点阵?
我敢打赌,就算是2位动态LED显示1~99,恐怕有一半的大三电子专业的学生不能独立做出来(一小时内)。

出0入0汤圆

 楼主| 发表于 2011-1-18 09:24:44 | 显示全部楼层
回复【72楼】luhuaren
改成  
if (x0 &lt; 8)  
    module_green1buffer[module][2*y0]  &amp;= ~(0x80&gt;&gt;x0);  
else   
    module_green1buffer[module][2*y0+1] &amp;= ~(0x80 &gt;&gt; (x0-8));  
如何?  
//===========================================================
~(0x80&gt;&gt;x0);
这句用查表效率是不是能高一点
-----------------------------------------------------------------------

效率是个总体的概念。包括执行时间和代码长度,两者有时候是矛盾的。好的程序员会根据实际情况,让两者都为最佳,达到总的效率为最好。

出0入0汤圆

 楼主| 发表于 2011-1-18 09:31:01 | 显示全部楼层
回复【75楼】lnskngdc
我觉得马老师说的有道理,看看现在学生的状态吧。
泡妞上网玩游戏,逃课挂科作弊,还有什么他们干不出来的?当然你们会说坏学生是少数。
周日跟朋友出去,听说了一个事情:
朋友公司招人,都是正经大学本科毕业的,单位大楼门口有三面国旗,左边是美国旗,中间是中国的,右边是加拿大的。
那位同学居然只认识中国国旗,同样的事情后来又发生在其他新人身上,这说明了什么?
个人素质差是一方面,可他们不是生来就差的,后面的就不说了。
另一方面,对于没见过的东西,如果不清楚原理,肯定三小时之内做不出来。
但学生们有多少人见过8*8led点阵?
我敢打赌,就算是2位动态led显示1~99,恐怕有一半的大三电子专业的学生不能独立做出来(一小时内)。

-----------------------------------------------------------------------

呕,偶的学生这个学期每2个学生发一块实验板,是带回家的,任何时间都可以玩。上面有8*8LED,还有一个规定的实验做8*8LED,我上课讲过例子,电梯的上升运动箭头,不会不认识的吧。

出0入0汤圆

发表于 2011-1-18 09:31:48 | 显示全部楼层
回复【72楼】luhuaren  
-----------------------------------------------------------------------

~(A >> B)这个计算有强指令集依赖。

对AVR来说,因为右移只有1Bit移位指令,因此查表速度会快。但是空间消耗大。需要平衡。

对ARM来说,可以用MVN Rd, Rm, LSR Rs这样一条指令直接全搞定。

出50入0汤圆

发表于 2011-1-18 09:32:36 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-1-18 09:34:09 | 显示全部楼层
要去考试了,好戏在后面。

出0入0汤圆

发表于 2011-1-18 09:35:29 | 显示全部楼层
呵呵,看出来马老师也喜欢用位操作啊,这样效率最高了:)

还有,那个switch case 的效率还不如if else 呢,至少我用ICCAVR试下来的效果是这样的。

这个题目我的思路是两个端口都位移,一个缓慢,显示用的,另一个就是常用的线扫描,周期短,至少50HZ,到边后两条线可以轮换。至于怎么编的漂亮,还有两条线能不能联合扫描起来没时间去多思考了,上班期间嘛:)

一会再来看看,期望能再学到点东西:)

------------------------------------------------------

相同功能的if else 和 switch 的反汇编代码以前我就看过的,我甚至一条一条数了对比的,差别很大啊......

对晶振最高上到16M的8位机来说,对于可能扔在中断中处理的代码来说,这点差别不能不考虑的......

出0入0汤圆

发表于 2011-1-18 09:42:50 | 显示全部楼层
大家看看CASE代码效率如何 ,还是不错的

(原文件名:case 汇编代码.JPG)

(原文件名:case 汇编代码2.JPG)

出0入0汤圆

发表于 2011-1-18 09:45:39 | 显示全部楼层
一共 8*4-4=28 种状态,行列各八根IO,那么总的数据存储量是 28*2*8 bit=56bytes,编好数组指定存在flash里面,这样简化了算法(不熟悉CVAVR,用的IAR),以下用伪代码,因为AVR已经很久不用,忘得差不多了。

__flash PA_DATA[28]={0b1000_0000,0b0100_0000,0b0010_0000,0b0001_0000,0b0000_1000,0b0000_0100,0b0000_0010,
                     0b0000_0001,0b0000_0001,0b0000_0001,0b0000_0001,0b0000_0001,0b0000_0001,0b0000_0001,
                     0b0000_0001,0b0000_0010,0b0000_0100,0b0000_1000,0b0001_0000,0b0010_0000,0b0100_0000,
                     0b1000_0000,0b1000_0000,0b1000_0000,0b1000_0000,0b1000_0000,0b1000_0000,0b1000_0000};

__flash PC_DATA[28]={0b1111_1110,0b1111_1110,0b1111_1110,0b1111_1110,0b1111_1110,0b1111_1110,0b1111_1110,
                     0b1111_1110,0b1111_1101,0b1111_1011,0b1111_0111,0b1110_1111,0b1101_1111,0b1011_1111,
                     0b0111_1111,0b0111_1111,0b0111_1111,0b0111_1111,0b0111_1111,0b0111_1111,0b0111_1111,
                     0b0111_1111,0b1011_1111,0b1101_1111,0b1110_1111,0b1111_0111,0b0111_1011,0b0111_1101};

unsigned char step    =  0x00;
unsigned char counter =  0x00;

// 根据87楼ada1983的提示 这里有bug,加了个扫描四个点的。马老师给个及格吧,哈哈,算作弊了。

main()
{
      // 配置管脚,初始化定时器,定时间隔为AVR能定的最大时长(可以被0.2S整除)
      system_init();
      while(1)
      {
           PortA=PA_DATA[step];
           PortC=PC_DATA[step];
           delay1();
           PortA=0b0001_1000;
           PortC=0b1110_0111;
           delay2();
      }
}

timer_handler()
{
      // 定时0.2S到
      if(counter=0xXX)
      {
           step++;
           if(step==28)
                 step=0x00;
           counter=0x00;
      }
      else
      {
           counter++;
      }
}

main部分行扫列扫那里和delay()的顺序可能需要微调,以消除重影。

这样完成题目1,思路=5min,敲以上内容=15min,查数据手册填完所有函数=60min(实在已经忘光所有AVR的东西了)。
delay1和delay2用于调节亮度绕圈点和中间四个点的亮度。


补充:有人提示bug+改动bug=20min,快不及格了。。。


如果要完成题目2,那么,需要将定时0xXX变成一个变量,在main里面的while循环中加一个按键扫描,更改0xXX改变速度。

杭州电子科技大学

出0入0汤圆

发表于 2011-1-18 09:50:54 | 显示全部楼层
没时间了 要上班了 下次再搞

出0入0汤圆

发表于 2011-1-18 09:53:37 | 显示全部楼层
回复【57楼】aleyn 煮茶村长

这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。
-----------------------------------------------------------------------

村长这个有点难为我们这些有点软件基础的电子专业学生了哈,这个的简单算法要想半天.当然如果中间四个灯不亮只是单纯绕螺旋线

倒是还好。

另外,马老师选的时间不对呀,这一阵子,本科生都在考试呢,估计没时间整这个,呵呵。

出0入0汤圆

发表于 2011-1-18 09:53:54 | 显示全部楼层
原来,名牌大学,也就这样(大多数),难怪我招人这么难,悲哀!

出0入0汤圆

发表于 2011-1-18 09:54:21 | 显示全部楼层
回复【83楼】McDeggy 再见,列宁
一共 8*4-4=28 种状态,行列各八根io,那么总的数据存储量是 28*2*8 bit=56bytes,编好数组指定存在flash里面,这样简化了算法(不熟悉cvavr,用的iar),以下用伪代码,因为avr已经很久不用,忘得差不多了。
__flash pa_data[28]={0b1000_0000,0b0100_0000,0b0010_0000,0b0001_0000,0b0000_1000,0b0000_0100,0b0000_0010,
                     0b0000_0001,0b0000_0001,0b0000_0001,0b0001_1001,0b0001_1001,0b0000_0001,0b0000_0001,
                     0b0000_0001,0b0000_0010,0b0000_0100,0b0000_......
-----------------------------------------------------------------------



你的这个程序好像不对,step变量0.2S才会改变,在主循环里无论怎么扫描,5个灯不会同时亮了,有BUG。

出0入0汤圆

发表于 2011-1-18 09:55:34 | 显示全部楼层
回复【82楼】jiangjx  
-----------------------------------------------------------------------

反汇编switch之后那几行看看吧,怎么跳转到case的那个分支树这里没显示。

出0入0汤圆

发表于 2011-1-18 09:56:31 | 显示全部楼层
这个如果做过显示数字的话就不难!

我觉得应该给个显示数字0-8的示例代码,在上面修改到想要的效果,这样会复合大多数人的胃口!

俺做硬件!路过酱油!

出0入0汤圆

发表于 2011-1-18 09:58:12 | 显示全部楼层
回复【66楼】machao
回复【57楼】aleyn 煮茶村长
这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。  
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。
-----------------------------------------------------------------------
软件专业?我不看好他们。这个不是在pc上编程,堆起来出效果就行了。看看jiangjx的代码吧,恐怕就是软件专业的。效率体现在哪里?8位mcu,程序空间是有限的。
这个题目不是设计一个通用的8*8led驱动,就完成一个简单的效果可以了。改为螺旋行转圈,恐怕95%的人不能在3个小时内完成。

-----------------------------------------------------------------------

只要实现打点函数  采用UCGUI 做出这种效果并不难

出0入0汤圆

发表于 2011-1-18 10:00:28 | 显示全部楼层
我看时间无算,能做出来的就是好学生!
更多的人是根本就不做,等有人做出来炒一下就OK,我上学时身边就有很多这样的例子!
记得当时(03年左右)课程设计,做个数码管电子钟加18b20,那是第一次写单片机程序,汇编的!完全实现的我们班就我一个(不是我吹牛啊),全专业不超过5个人(我知道的连我3个人),有的人是没做完,大多数是根本没做,在玩游戏,那是学校网速很慢,玩的都是挖地雷!

出0入0汤圆

发表于 2011-1-18 10:03:20 | 显示全部楼层
回复【87楼】ada1983

回复【83楼】McDeggy 再见,列宁
一共 8*4-4=28 种状态,行列各八根io,那么总的数据存储量是 28*2*8 bit=56bytes,编好数组指定存在flash里面,这样简化了算法(不熟悉cvavr,用的iar),以下用伪代码,因为avr已经很久不用,忘得差不多了。  
__flash pa_data[28]={0b1000_0000,0b0100_0000,0b0010_0000,0b0001_0000,0b0000_1000,0b0000_0100,0b0000_0010,  
                     0b0000_0001,0b0000_0001,0b0000_0001,0b0001_1001,0b0001_1001,0b0000_0001,0b0000_0001,  
                     0b0000_0001,0b0000_0010,0b0000_0100,0b0000_......
-----------------------------------------------------------------------



你的这个程序好像不对,step变量0.2S才会改变,在主循环里无论怎么扫描,5个灯不会同时亮了,有BUG。
-----------------------------------------------------------------------
对哦,这个忘了,那要改变flash里面的状态了,失误失误

出0入0汤圆

发表于 2011-1-18 10:05:18 | 显示全部楼层
没嘛意义,学生连单片机都没见过的都很多。我出校门的时候c语言也不好,一知半解,到头来不还是做技术。因为做技术已经是在这个社会上比较容易的工作了,以时间换空间。

出0入0汤圆

发表于 2011-1-18 10:06:18 | 显示全部楼层
回复【90楼】jiangjx
回复【66楼】machao  
回复【57楼】aleyn 煮茶村长  
这题对於有点电子基础的软件专业学生来说,问题不大,但“倒过来”就不一定了。   
不如,再加点点?把那个流水灯的单纯转圈改为螺旋行转圈,其它条件不变。  
-----------------------------------------------------------------------  
软件专业?我不看好他们。这个不是在pc上编程,堆起来出效果就行了。看看jiangjx的代码吧,恐怕就是软件专业的。效率体现在哪里?8位mcu,程序空间是有限的。  
这个题目不是设计一个通用的8*8led驱动,就完成一个简单的效果可以了。改为螺旋行转圈,恐怕95%的人不能在3个小时内完成。  
----------------------------------------------------------------......
-----------------------------------------------------------------------

一个8位机,MEGA16(看到老师图上的16代号了),你指望它跑个OS?再加个UCGUI?当然,你能用MEGA16移植个精简的OS和UCGUI的话也很牛叉了,我想大多数人会崇拜你的,老师也会觉得不错:)

出0入0汤圆

发表于 2011-1-18 10:11:59 | 显示全部楼层
小弟贴上代码,欢迎拍砖,没有测试过,用时差不多1个小时,虽然看起来挺简单的,但是做起来还是挺麻烦的
看到北大,华师大 呵呵 我都不好意思报自己的学校了~
马老师说要报上学校 呵呵 我也就报上了 希望别丢母校的脸~
本人09年7月毕业于 上海师范大学~

#define                T1_COUNT                200u
#define                LED_NUM                        7

enun
{
        false,
        true,
};

enum
{
        OFF,
        ON,
};

unsigned char T1_1ms;
unsigned char T1_1ms_flag;
unsigned char T1_200ms_flag;

unsigned char four_Led_state = OFF;
unsigned char x_location = 0;
unsigned char y_location = 0;

//定时器中断 1ms
void timer1_interrupt(void)
{
        T1_1ms ++;
        T1_1ms_flag = true;
        if(T1_1ms % T1_COUNT == 0)
        {
                T1_1ms = 0;
                T1_200ms_flag = true;
        }
}

void Led_four(void)
{
        if(four_Led_state == OFF)
                four_Led_state = ON;
        else if(four_Led_state == ON)
                four_Led_state = OFF;
        PA3 = four_Led_state;
        PA4 = four_Led_state;
        PC3 = four_Led_state;
        PC4 = four_Led_state;
}

void Round_Led(unsigned char x,unsigned char y,unsigned char state)
{
        if(state == ON)
        {
                PA &= x;
                PC &= y;
        }
        else if(state = OFF)
        {
                PA = 0;
                PC = 0;
        }
}

void main(void)
{
        if(T1_200ms_flag == true)
        {
                T1_200ms_flag = false;
                Round_Led(1<<x_location,1<<y_location,OFF);
                if(x_location == 0)
                {
                        if(y_location == 0)
                                x_location ++;
                        else if(y_location > 0)
                                y_location --;
                }
                else if(x_location < LED_NUM)
                {
                        if(y_location == 0)
                                x_location ++;
                        else if(y_location == LED_NUM)
                                x_location --;
                }
                else if (x_location == LED_NUM)
                {
                        if(y_location < LED_NUM)
                                y_location ++;
                        else if (y_location == LED_NUM)
                                x_location --;
                }
                Round_Led(1<<x_location,1<<y_location,ON);
        }

        if(T1_1ms_flag == true)
        {
                T1_1ms_flag = false;
                Led_four();
                Round_Led(1<<x_location,1<<y_location,ON);
        }
}

出0入0汤圆

发表于 2011-1-18 10:16:25 | 显示全部楼层
忙里偷闲再说下我的体会。

这个和一般的数码管扫描不一样,一般的数码管扫描一根线就可以了,在这里要把中间那四个点配合显示出来的话可能需要两个口轮流做扫描线。

还有,动态扫描的时候还必须主意两个端口的配合,不然可能出现不想显示的点亮一下就灭的情况,四个顶点那里尤其要注意。

说的不对的大家拍砖啊,我也能多学点:)

出0入0汤圆

发表于 2011-1-18 10:18:16 | 显示全部楼层
做成数据表格显示是一种方式,取表格的中间延时决定了流水的快慢。数据加减运算也是一种方式,运算时间+延时时间=流水的快慢。

出0入0汤圆

发表于 2011-1-18 10:24:14 | 显示全部楼层
回复【97楼】fei_yang

做成数据表格显示是一种方式,取表格的中间延时决定了流水的快慢。数据加减运算也是一种方式,运算时间+延时时间=流水的快慢。
-----------------------------------------------------------------------

你这样流水很难准确定时为0.2S,如果再加上按键扫描那就更不准了。

出0入0汤圆

发表于 2011-1-18 10:27:02 | 显示全部楼层
回复【96楼】ada1983

忙里偷闲再说下我的体会。

这个和一般的数码管扫描不一样,一般的数码管扫描一根线就可以了,在这里要把中间那四个点配合显示出来的话可能需要两个口轮流做扫描线。

还有,动态扫描的时候还必须主意两个端口的配合,不然可能出现不想显示的点亮一下就灭的情况,四个顶点那里尤其要注意。

说的不对的大家拍砖啊,我也能多学点:)
-----------------------------------------------------------------------

ada1983也贴个代码来学习一下嘛,大早上到实验室,结果在这个帖子上浏览了大半天,貌似就没几个贴代码的。

你说的是残影问题吧,调整动态扫描两个口之间的开关动作和延时时间可以大大缓解这个问题。

貌似马老师消失很久了。。。

出0入0汤圆

发表于 2011-1-18 10:27:16 | 显示全部楼层
回复【98楼】McDeggy 再见,列宁
-----------------------------------------------------------------------

取一次数据要多长时间?

出0入0汤圆

发表于 2011-1-18 10:27:40 | 显示全部楼层
手机看帖,杯具
如果是二维数组显示矢量图形,我表示鸭梨很大

出0入0汤圆

发表于 2011-1-18 10:29:39 | 显示全部楼层
1:可以开两个定时器对LED扫描,一个运动点,四个静态点。
2:28个运动点,按照T累加,按点计算位置,确定段码。
3:主函数扫描键盘,对进行累加,当然需要消抖延时。
不懂AVR,只是谈谈思路!

出0入0汤圆

发表于 2011-1-18 10:30:01 | 显示全部楼层
mark!

出0入42汤圆

发表于 2011-1-18 10:32:45 | 显示全部楼层
void scan(void)
{
    static unsigned char sRow=0;
    sRow =(--sRow)&0x07;
    PORTA = ~(1<<sRow);
    PORTB = (sRow==row)<<col;
    if ((~PORTA)&0x18) {
        PORTB |= 0x18;
    }
}

/*6.25ms*/
ISR(TIM0_OVF_vect)
{
    scan();
    //volatile global counter
    counter = (++counter)&0x1F; //%32
    if (!counter) {
        goNext();
    }
}

出0入0汤圆

发表于 2011-1-18 10:40:40 | 显示全部楼层
回复【102楼】catvevs
-----------------------------------------------------------------------

没有必要!静态点是因为显示的数据有某几个位一直不变,还开定时器干吗?一个足够了,只需更新变化的数据,不变的位让它一直不变。
对于按键带来的延时可以用中断消除,即用定时器的中断来更新数据,而不是在主函数更新。

当年俺单片机考了60分,全年级99.9%的考了90分以上!我也是最后交卷的一个。普通二本,学校就不说了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 20:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表