machao 发表于 2007-5-8 14:51:33

《AVR单片机嵌入式系统原理与应用实践》---第二篇 基本接口单元的应用设计(2),9-11

============================================================
    本人上贴的书稿,允许其它网站或个人免费收集下载或全部/部分转贴,打印使用。但不准从事商业应用,如收费下载,将全部内容或部分内容整理出版等。在公开场合,诸如网站下载、课堂教学、公司培训等,使用全部或部分内容时,务必加上以下来源说明:

本书稿是由上海华东师范大学信息学院电子科学技术系马潮副教授根据其本人多年从事硬件、软件以及单片嵌入式系统教学和培训的经验,并结合实际应用项目开发过程中的实践积累整理编写。书名定为《AVR单片机嵌入式系统原理与应用实践》,该书已经列入教育部的“普通高等教育“十一五”国家级规划教材”,2007年10月已由北航出版社出版。

                              本书作者
=============================================================

根据本人多年从事AVR教学、培训和应用开发的经验积累,对本版中的讲义进行了整理和修改,并准备出版。

    书名定为《基于AVR的单片嵌入式系统原理与应用实践》,该书已经列入教育部的“普通高等教育“十一五”国家级规划教材”,将由北航出版社出版。

    目前本书书稿正在抓紧整理和修改之中,现将已经整理完成的第二篇(2)后3章内容贴上,请大家参考,并提出意见和建议。如发现错误请及时通知我。


点击此处下载"第二篇 基本接口单元的应用设计(2)".rar(2M)

请将阅读过程中发现的问题,以及错别字等及时贴在下面。谢谢!====

请将阅读过程中发现的问题,以及错别字等及时贴在下面。谢谢!

CHXUEAVR 发表于 2007-5-8 17:04:17

马老师太好了!刚好是我需要的.

我第一个下载.

testcode 发表于 2007-5-9 02:38:03

谢谢马老师

wuyunzdh 发表于 2007-5-11 14:23:27

马老师是一位一切为学生考虑的好老师,这是我最深的感触!

gxlujd 发表于 2007-5-11 16:00:37

向马老师致敬!

machao 发表于 2007-5-12 16:10:26

最好的感谢,请看后帮助找问题,提意见了。

jianglongjian 发表于 2007-5-15 21:20:58

第八章的24页中:

“由于人眼不能分辨42Hz以上的频率,所以PWM的频率应高于42Hz,否则人眼会察觉到灯的闪烁。”这里面有没写错了,PWM的频率应低于42Hz



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

这个没有问题。PWM频率低于42HZ,人眼看上去就有闪烁了。

gkw9142 发表于 2007-5-31 09:02:23

关于6楼提出的问题



  马老师的意思是好像是:要通过PWM调节白炽灯的亮度,实现类似无级调速的功能,照明用的白炽灯是不允许闪烁的。而6楼的目的好像是要用灯来闪烁而不是照明。

  首先、关于通过PWM调节白炽灯的亮度。马老师在课上好像是这样描述的:由于PWM输出是数字信号,而我们在实际使用中多数是使用模拟量(例如:使用的是电压而不是占空比),所以有时我们要在PWM的输出上加上一个低通滤波器(或则说是 积分器),把占空比可调的数字信号转化为模拟信号,这样我们就实现了DAC。在作电灯时,我们可以把这个LPF去掉,由于人眼不能分辨42Hz以上的频率,高频不能分辨就意味着低通滤波器(笔注1),虽然我们没有在电路上加LPF,白炽灯是在闪烁,但由于人眼睛具有LPF的特点,大脑接收到的信号实际已经是模拟量。 这样人看到的白炽灯不是在闪烁,而是亮度在变。

  通过马老师在课上的描述,我觉得马老师的意思是好像是:要通过PWM调节白炽灯的亮度,实现类似无级调速的功能。希望马老师在教案上加上这个功能描述。



  其次,关于闪烁。我们的U盘,用LED闪烁来作指示信号,好像是这样的:有电源--0Hz,工作--2Hz,忙--12Hz。我觉得用闪烁来做指示信号1~15Hz就可以了,15Hz以上我们就是在看电影勒。闪烁的频率、亮度、持续时间对人的舒适度影响很大,一般闪烁的亮度不要太大(个人感觉手机用蓝光来做闪烁纯的是视觉污染),如果是高亮度照明、显示那就不要有闪烁,否则人会很累的。



笔注1:眼睛是通过视网膜上的类胡萝卜素顺态逆态转换来实现对光的感知,在无光强的时候是顺态有光强的时候是逆态(顺态逆态类似于高低电平)。类胡萝卜素的顺态逆态转换平均约0.01S的时间,或者说类胡萝卜素的态转换需要约0.01S的延时,这种机制相当于电容的充放电,而转换延时所造成的相移在相频特性上类似于低通。

jeff_4 发表于 2007-6-3 09:36:21

7楼的是生物系的吧。搞那么多名词,感觉自己很牛!是吧。

说清楚不就得了。

只要知道常识,我们看日光灯白炽灯都不闪的(除少数人觉得自己异于常人),而它们频闪是多少?50Hz,50Hz〉42Hz,直接就证明了高于42Hz人眼看着不闪。

反过来,自己动手做个实验,看多少频率人眼看着不闪,是高于还是低于一下子一目了然了。

纸上谈兵永远就是谈而已。

实践是检验真理的唯一标准。

wxwdxx 发表于 2007-6-9 17:47:56

不知马老师11章以后的东西怎么得到?马老师的书什么时候能出啊?



选课结束了,04级的微电子和通讯下学期都没有马潮老师的课。想学以后的章节就困难了啊。

lcd128x64 发表于 2007-7-31 21:48:27

向所有实实在在教书育人的人类灵魂工程师说声“谢谢了”。

啥时候书能出版?./emotion/em086.gif

2004111102 发表于 2007-8-5 20:51:27

马老师,第十二章呢,

2004111102 发表于 2007-8-6 09:38:26

向马老师提个建议:

第一:你的这本书好象例子少了些,如果你再加上一些,我想效果会更好!

第二:由于AVR的寄存器很多,记忆很不方便,如果能在每讲到某一寄存器的某一位时,都列出这个寄存器的每一位,这样,对读者来说,应是方便很多,很多书都没有做到这一点,但作为一个初接触者,在这方面我的感受很多;

第三:电路图也一样,能在用的地方就贴上,这样在看书时也很方便;

顺带指出,第十一章第8页T0的工作方式没有在注解里指出,那里好像是掉了一个字.

问个问题:就如第十一章第8页那里所说的,"因此在1ms时间内,程序必须将脉冲个数进行的累计、BCD码转换和送入显示缓冲区,以及LED的扫描工作完成掉,否则就会影响到下一次中断到来后的处理",那我如何知道这段程序能否在1MS内完成呢,有什么方法?

caiyb 发表于 2007-8-11 13:38:21

多谢马老师!

yy305196456 发表于 2007-8-11 23:45:43

马老师:



    你好!我有个问题想向你请教。我最近在调试一个AVR单片机程序(型号为:ATMEGA8-16PU),不知道为什么程序总是在主程序中死循环,即使我在主程序中使用了while,它也会把while前面的程序重新执行一遍。现象就像是板子在反复Reset一样。而我的电压一直是稳定的,请问到底发生了什么事?



程序代码如下:

int main(void)

{       

        init_usart(); //串口初始化程序,仿阿莫同志提供的示例程序

        DDRC |= (1<<PC3)+(1<<PC4)+(1<<PC5); //与LED灯相连的三个IO口,均设置为输出方式       

        put_c(0x11);//串口输出一字节,用于调试       

        sei();        //开中断指令       

        LED_D1_ON(); //亮灯LED1

        LED_D2_ON(); //亮灯LED2

        LED_D3_OFF();//灭灯LED3

               

        while(1)

        {

                ;               

        }       

}



现象是:串口一直出现0x11这一数据。



麻烦你了,谢谢!

machao 发表于 2007-8-12 00:10:23

为什么开中断?



把开中断指令去掉试试,如果可以的话,可能在你的init_usart();里面有问题。

yy305196456 发表于 2007-8-12 11:46:31

我全部程序代码我传给你看一下吧!



//全局变量

//如果变量会在中断服务程序中被修改,须加volatile限定

volatile unsigned char PC_COMMAND;                //PC发出的当前命令



/**********************************************************

** 函数名称: put_c

** 功能描述: 采用查询方式通过UART发送一个字节

** 输 入: c:待发送的数据

**********************************************************/

void put_c(char c)

{

        while( !(UCSRA & (1<<UDRE)) );

        UDR=c;

        UCSRA|=(1<<UDRE);

}



/**********************************************************

** 函数名称: put_s

** 功能描述: 采用查询方式通过UART发送一串数据

** 输 入: ptr:待发送数据串的首地址

**

**********************************************************/

void put_s(char *ptr)

{

        while (*ptr)

        {

                if ((*ptr) == '
')

                {

                        put_c(0x0D);

                        put_c(0x0A);//结尾发送回车换行

                        break;

                }

                put_c(*ptr++);

        }

}





/**********************************************************

** 函数名称: init_usart

** 功能描述: 初始化串口

**

**********************************************************/

void init_usart(void)

{

    //USART 9600 8, n,1PC上位机软件(超级终端等)也要设成同样的设置才能通讯

    UCSRC = (1<<URSEL) | (0x06);

    //异步,8位数据,无奇偶校验,一个停止位,无倍速

    UBRRL= (F_CPU/BAUDRATE/16-1)%256;

    UBRRH= (F_CPU/BAUDRATE/16-1)/256;

    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);;

    //使能接收中断,使能接收,使能发送

}



/**********************************************************

** 函数名称: init_port

** 功能描述: 初始化IO口

**

**********************************************************/

void init_port(void)

{       

       DDRC |= (1<<PC3)+(1<<PC4)+(1<<PC5); //与LED灯相连的三个IO口,均设置为输出方式       

}



/**********************************************************

** 函数名称: init

** 功能描述: 系统初始化

**

**********************************************************/       

void init(void)       

{

        init_port();       

        init_usart();

}



/**********************************************************

** 函数名称: main

** 功能描述: 主函数

**

**********************************************************/       

int main(void)

{       

        init(); //串口初始化程序,仿阿莫同志提供的示例程序

        put_c(0x11);//串口输出一字节,用于调试       

        sei();        //开中断指令       

               

        while(1)

        {

                ;               

        }       

}





/********************************************************************

** 函数名称: SIGNAL(SIG_UART_RECV)

** 功能描述: 串口接收中断的服务程序

**

***********************************************************************/

SIGNAL(SIG_UART_RECV)

{

        cli();

        PC_COMMAND=UDR;

        switch(PC_COMMAND)

        {

                case '1':        //0x30 ASCII '0'

                        put_s("用户输入0#指令");

                        break;

                case '2':

                        put_s("用户输入1#指令");

                        break;

                case '3':

                        put_s("用户输入2#指令");

                        break;

                default:

                        put_s("用户输入的指令无效!");

                        break;

        }

        sei();

}

yy305196456 发表于 2007-8-12 11:56:38

谢谢马老师这么及时的答复。我的问题还有就是:同样的程序,我在有些AVR开发板上(型号:atmega8l 8AI以运行,在另外一些板子上(型号:atmega8l-8PI/16PU)却不能运行,请问原因主要出在哪里?

yy305196456 发表于 2007-8-13 11:28:05

马老师,

    你好!我已经找出原因了,因为,在熔丝配置时,打开了"开门狗"!呵呵!谢谢你了!

machao 发表于 2007-8-13 13:33:17

恭喜你了。



我在讲义的前面已经特别的强调注意不要乱动熔丝位的配置了。



AVR的WDT出厂是关闭的,我曾经使用过一块改进51,它的WDT出厂就是开的,一开始也出现你的问题。不过很快解决了,可能是经验多一点。



这种经验只能在实践中学习了,下次发生类似的情况,你就能马上解决了。

mtxmxt 发表于 2007-8-17 16:20:45

如果变量会在中断服务程序中被修改,须加volatile限定?

上面这段描述好象不对吧,volatile是表明该变量会随时改变,不须优化

jinbu 发表于 2007-8-30 14:34:35

感谢马老师的无私共享,有个问题想问下马老师:

1.当AVR在执行定时器中断程序时,定时器是继续走还是等处理完中断程序后走?

2.当AVR在执行其他中断程序时(比如外部中断),定时器是继续走还是等处理完中断程序后在走?

我的理解是:

1。当AVR在执行定时器中断时,比如定时器0中断,定时器0要等处理完中断后再走,而其他定时器(比如定时器1)则继续走

2.当AVR在执行其他中断时,定时器继续走

初学者请教,谢谢

machao 发表于 2007-8-30 15:23:10

21楼:



定时器是硬件单元,只要有计数脉冲输入,计数器本身就一直处在计数工作状态,不会停止。不管执行什么中断,定时器按你设置的工作方式一直工作。



所以你的1是错误的。

jinbu 发表于 2007-9-27 16:29:03

马老师您好:首先说明,我是一个初学者,以下的观点不一定正确,请马老师指点.
   关于您的"基于AVR的单片嵌入式系统原理与应用实践---第二篇 基本接口单元的应用设计(2),9-11章"其中第10章有个简易电压表的实际与实现的例子,我仔细看了这个例子,觉得程序有问题,如下:
   1.第一个2mS来的时候ADC转换结束并送电压值入显示的缓冲区,并且开始扫描显示LED的第一位
   2.第二个2mS来的时候ADC第二次转换结束并送电压值入显示的缓冲区,此时扫描显示LED的第二位
这就带来一个问题,第一次2mS显示的值是第一次AD转换电压的第一位,第二次2mS显示的值是第二次AD转换电压的第二位,这明显是错误的.
   不知道我的分析是否真确,如果错了,请大家不要骂我,哈哈,我再仔细看下.......,不知道马老师能不能帮我分析下呢?谢谢!

machao 发表于 2007-9-27 18:38:53

回23楼,当你在实际情况下运行后可以观察具体的显示。有些情况理论上的分析还要同实际的现实世界配合。

如同时钟显示的动态扫描方式,理论上点亮的只是一个LED数码管,当你满足一定方式时,现实看上去6个LED数码管都亮。

在电压表的例子中,你的理论分析是正确的。但我们测量的电压变化是缓慢变化的,通常情况连续几十次ADC的转换值是相同的,所以显示的数字保持不变。

如果在2ms间隔的测量过程中,ADC的转换电压总是在改变,那你就是将每一次的ADC转换结果全部显示(使用LCD显示就可以了),那你实际看到的电压值也在不停的变化。

作为简单的电压表,电压的测量与LED的显示需要合理的安排。在实际应用中,你可以调节输入的直流电压,看显示变化能否正确的、并跟的上你的调节过程,作到一旦调节完成,显示也就稳定。你也可以每隔6ms进行一次ADC转换,转换的结果送LED扫描显示,2ms显示一位。

jinbu 发表于 2007-9-28 09:07:57

谢谢马老师的辅导,您的这种方法很好,我一直找不到一种当AD转换后实时显示的方法,您的这种方法给了我一个启发.您的这本书真的很好,好好学习我想我会提高很快的,谢谢!

canking 发表于 2007-9-28 09:52:37

多谢马老师啊,我要慢慢学啊

XXHF 发表于 2007-10-7 21:23:03

谢马老师...什么时候才有书出来啊?????

jinbu 发表于 2007-10-11 10:41:28

马老师:您的第10章"模拟比较器的应用设计"中有个例子:在5V的系统中,LED串了一个500欧的电阻,我对LED的工作条件一直很迷茫,于是我就做了一个实验:
    1.LED串10K的电阻,LED亮,LED电压为1.72V
    2.LED串4.7K的电阻,LED亮度增加,LED电压为1.74V
    3.LED串470的电阻,LED亮度最亮,LED电压为1.89V
在百读上的回答是:
    LED耗电非常低,一般来说LED的工作电压是2-3.6V。工作电流是0.02-0.03A。这就是说:它消耗的电不超过0.1W。
我已经彻底迷茫了,呵呵.
请问马老师,LED的工作条件有个比较标准的规定吗?从我的实验结果来看,串一个10K的电阻是可以的,但是亮度不太够,串一个4.7K的电阻是比较理想的.

wqsjob 发表于 2007-11-22 14:15:05

正常设计时,LED电流不应超过20MA,这时LED分压大概2V左右,而我一般是按1.7V分压算电流,和28楼测试结果比较类似。:),多谢你测试了数据。
说功耗非常低,是针对以前的电路而言。
另外,LED设计,一般在3-5MA就够了,也可以3MA以下。当然尽量选用高亮度的,毕竟低功耗低点好。

machao 发表于 2007-11-22 16:20:31

现在的LED数码管多为高亮度,每段按3-5mA算.LED最大到10mA,一般在5-8mA.指一般的.大个的需要了解厂家和测试.

daydream 发表于 2007-11-23 21:15:49

已经下载完前两篇.谢谢马老师!
顺便问一下:电子版中是否为修改后的最终版本?

machao 发表于 2007-11-23 21:35:22

to 31楼:

基本上相同.不过书中少了很多错字,排版也比电子版的好,看起来舒服些.如果电子版的够用,就不必买书,太贵了^_^

dzh2800 发表于 2007-12-2 21:26:20

谢马老师!!!

Chenxg 发表于 2007-12-4 09:37:06

谢谢马老师

liaoxiaoqing 发表于 2007-12-5 17:58:32

第十二章之后的呢?
怎么没有呀?

machao 发表于 2007-12-5 21:19:08

十二章以后的内容在新出的书中,本书10月下旬已经由北航出版社出版.

如果楼上看了前十一章内容后,认为确有参考价值的话,可以购买本书.

本书是教育部的“普通高等教育“十一五”国家级规划教材”

simonxx 发表于 2007-12-16 22:37:10

我是新手,对马老师的无私奉献致敬!!

enjoy 发表于 2007-12-28 18:36:09

刚学AVR单片机,正在考虑买这本书呢,请问楼主,这本书怎么样??
谢谢!

machao 发表于 2007-12-29 02:38:15

这里不是有本书前2篇的内容吗?你可以先下载学习,如果觉的有参考价值,再购买.

aohaijun 发表于 2008-1-15 18:46:40

多谢马老师,我刚刚开始学AVR,网上象样的又教程很少,难得碰到老师这样的人!!!

neobean 发表于 2008-3-23 20:32:48

感谢马老师的无私奉献!!!虽然下载并且浏览了电子版教材,不过个人认为购买这两本教材是提高自己水平和支持老师奉献的最好报答,世上多些像马老师这样的人就太好了。马老师对无私行为是被大家肯定的。

machao 发表于 2008-3-25 00:07:17

过了,无私谈不上.但如果书对你真正有帮助我还是非常高兴的.

yzz163 发表于 2008-3-26 12:00:34

我觉得用闪烁来做指示信号1~15Hz就可以了,15Hz以上我们就是在看电影勒。
---------------------------------

载自:《黑白电视机 原理-调试-设计》 第一章,第2页
因为从实践中发现,如果每秒放映的幅数小于48,我们看起来就有闪烁跳动的感觉,当然它还与放映的亮度有关。


因此马老师的这句“由于人眼不能分辨42Hz以上的频率,所以PWM的频率应高于42Hz,否则人眼会察觉到灯的闪烁。”是对的。

此外,(胶片)电影是 每秒放 24幅不同的胶片,(为避免播放时出现闪烁跳动的感觉)每张胶片播放两次,也就是每秒放 48幅(张)胶片,即48Hz。
电视机里是 50副/场(PAL中国制),是因为考虑到220V交流电为50Hz,这样可减少电源的干扰。

另:为了感激马老师及OURAVR,在AM的邮购部 买了这本书。

djbgreen 发表于 2008-5-27 21:26:17

非常感谢马老师!

chenguang520 发表于 2008-6-3 08:58:39

向所有实实在在教书育人的人类灵魂工程师说声“谢谢了”。
啥时候书能出版?

machao 发表于 2008-6-3 19:02:20

楼上的,在LZ位已经说明了,本书去年10月已经出版了.这里提供下载的是前两篇的电子稿,可以先下载看看,觉的有用再买书.

yangyancpst 发表于 2008-6-17 15:50:45

马老师的书什么时候能出啊

machao 发表于 2008-6-17 15:53:22

咳,47楼的朋友,在46楼已经讲了.

你也是这样看书的?

happyandsafe 发表于 2008-6-25 15:13:36

谢谢马老师,我最近在北航图书馆正专研您的书,挺适用的。

littlepig 发表于 2009-4-19 21:50:29

thanks a lot

ahu55555 发表于 2009-4-22 12:50:58

什么时候马老师出书了我肯定支持买的

weifeng99 发表于 2009-6-6 18:14:41

谢谢马老师

psocfans 发表于 2009-8-1 17:35:10

谢谢马老师

qls2009 发表于 2009-9-12 16:46:07

非常感谢马老师

hnrain 发表于 2009-9-15 11:58:16

嗯。。。感谢马老师

wisebaby 发表于 2009-9-15 12:05:58

感谢马老师.

coldwind 发表于 2009-9-16 22:11:40

谢谢

马老师

lizhe159 发表于 2009-11-12 21:27:46

谢谢

438219660 发表于 2010-7-31 23:25:16

谢谢马老师

guxingganyue 发表于 2010-11-1 21:14:25

mark

czxf 发表于 2010-11-2 19:19:10

好书,买!

zbazba 发表于 2011-1-8 22:21:20

P335 页第二行   Else -------->>>>>>>> else

zbazba 发表于 2011-1-8 22:34:20

demo_11_3 而且好像少了几个{}嘛

imjacob 发表于 2011-2-7 16:20:03

mark

shunda 发表于 2011-5-4 22:23:43

CooL.WD 发表于 2011-5-17 02:31:44

虽然,我是4年后来拜读,我还是谢谢马老师了

p125abc 发表于 2011-5-24 10:21:50

现在 正在学习,谢谢了 老师

535727234 发表于 2011-8-11 17:48:36

当当有了

zhuilovelyan 发表于 2011-8-31 18:41:30

顶一个,加油,马老师

nomsg 发表于 2011-11-9 18:38:18

mark

enovo2468 发表于 2012-2-16 19:54:44

mark
页: [1]
查看完整版本: 《AVR单片机嵌入式系统原理与应用实践》---第二篇 基本接口单元的应用设计(2),9-11