作者存档: 奔跑 - 第20页

C语言测试:想成为嵌入式程序员应知道的0x10个基本问题

本来是想搜索怎样测试C语言编写的嵌入式程序,碰巧找到了这篇文章,觉得不错,转载下,回头仔细看看。
查看原文

C语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在这过程中我意识到这些测试能为带面试者和被面试者提供许多有用信息,此外,撇开面试的压力不谈,这种测试也是相当有趣的。
从被面试者的角度来讲,你能了解许多关于出题者或监考者的情况。这个测试只是出题者为显示其对ANSI标准细节的知识而不是技术技巧而设计吗?这个愚蠢的问题吗?如要你答出某个字符的ASCII值。这些问题着重考察你的系统调用和内存分配策略方面的能力吗?这标志着出题者也许花时间在微机上而不上在嵌入式系统上。如果上述任何问题的答案是“是”的话,那么我知道我得认真考虑我是否应该去做这份工作。
从面试者的角度来讲,一个测试也许能从多方面揭示应试者的素质:最基本的,你能了解应试者C语言的水平。不管怎么样,看一下这人如何回答他不会的问题也是满有趣。应试者是以好的直觉做出明智的选择,还是只是瞎蒙呢?当应试者在某个问题上卡住时是找借口呢,还是表现出对问题的真正的好奇心,把这看成学习的机会呢?我发现这些信息与他们的测试成绩一样有用。
有了这些想法,我决定出一些真正针对嵌入式系统的考题,希望这些令人头痛的考题能给正在找工作的人一点帮住。这些问题都是我这些年实际碰到的。其中有些题很难,但它们应该都能给你一点启迪。
这个测试适于不同水平的应试者,大多数初级水平的应试者的成绩会很差,经验丰富的程序员应该有很好的成绩。为了让你能自己决定某些问题的偏好,每个问题没有分配分数,如果选择这些考题为你所用,请自行按你的意思分配分数。 继续阅读 »

关于编辑器EditPlus

本文转自:http://zorro.blog.51cto.com/2139862/856553

引子
可以说文本编辑器是人们用得最多的软件之一,不管是家用还是办公,还是编程、作网页,虽然Windows本身的Notepad很简陋,但是有许多功能强大的共享编辑器软件让我们选择,比如UltraEdit、EditPlus、SynEdit、EditPad等,熟练掌握一款具有代表性的编辑器的详细用法,能够大大提高我们的工作效率。

EditPlus是非常有名的文本编辑器,它功能强大,特色丰富,中文兼容性好,是许多朋友必备的工具之一。下面,为大家详细介绍这个软件的使用。需要说明的是,本文试图以循序渐进的方式讲述。   对于许多应用程序,大部分操作使用键盘要快于鼠标,特别是文本编辑工具,更是如此。许多命令如果不用键盘操作就失去了存在的意义,因为用鼠标在选单里面一步步选取,相当不便。如果经常与编辑器打交道,掌握快捷键的操作很重要,可以节约很多时间。不必刻意去记忆,在使用过程里自然而然就会掌握。因为EditPlus的所有快捷键都可以由用户定义、修改,本文介绍各个命令时,以选单为主。 继续阅读 »

关于STM32使用RTC时复位后程序死在 RTC_WaitForSynchro() 函数中的问题

出现的现象:使用野火的RTC例程,在软件仿真时如果不需要配置,则程序会死在 RTC_WaitForSynchro() 函数中。而下载到硬件上时,有时候可以跑,有时候也会在该函数中死循环。

可能的原因:
首先,一定要确认是否使能了对后备寄存器和RTC的访问。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操
作。执行以下操作将使能对后备寄存器和RTC的访问: 继续阅读 »

MSP430F2232使用ADC进行系统电池电压监测

MSP22x2内部10位ADC用来进行系统电压检测。使用内部1.5V参考源,P2.0作为电池电压检测口。外部使用3M:1M分压电路。电压门限选定为2.45V和2.75V,对应的ADC的值为418和468。ADC满量程为1023,对应1.5电压。
ADC10采集函数: 继续阅读 »

MSP430使用TimerB定时进行传感器数据采集时遇到的定时错误

 问题现象:
在数据采集时一段时间会出现停止采集的情况,经过在线debug发现此时TBCCR0的值和TBR的值相差约为1.3s,即1.3s后才会再次产生TB0中断,才会再次采集数据。

使用背景:

用TB0做传感器定时采集,因为向传感器发送采集命令后要等待大约6ms才能获取到传感器数据,所以TB0的中断逻辑如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 __interrupt void Timer_B0_ISR(void)
 {
 TBCCTL0 &= ~CCIE;  //关闭中断
 switch (SampleCtrl.State)
 {
 case SAMPLE_STATE_SEND:   //发送采集命令
 LED2ON;
 TBCCR0 = TBR + 262;   //8ms
 发送采集命令;
 SampleCtrl.State = SAMPLE_STATE_READ;
 break;
 case SAMPLE_STATE_READ:   //读取采集结果
 if (g_bDRDYFlg)   //DRDY脚中断使该标志置位,表明一次数据采集完成
 {
 g_bDRDYFlg = FALSE;
 SampleCtrl.State = SAMPLE_STATE_SEND;
 if  //采集的数据有效
 {
 EventReqQue |= DETECT_VEHICLE;
 //完成一次采集,设置剩余定时时间
 if (SAMPLE_FREQ_HI == SampleCtrl.Freq)  //设置为10ms-8ms
 {
 TBCCR0 = TBR + 65;   //2ms
 }
 else                                    //设置为100ms-32ms
 {
 TBCCR0 = TBR + 3014;   //92ms
 }
 LPM3_EXIT;
 }
 else  //采集的数据无效
 {
 TBCCR0 = TBR + 20;
 }
 }
 else  //数据采集尚未完成
 {
 TBCCR0 = TBR + 20;   //约60us后再次进入中断,再去读取数据。
 }
 break;
 default:
 SampleCtrl.State = SAMPLE_STATE_SEND;
 break;
 }
1
 
1
}

 

 问题原因:
由于在传感器数据采集时还需要跟24L01通信,为了保证SPI通信可靠,读写24L01时禁止了地磁采集,而禁止地磁采集时只是禁止了TB0中断,并没有停止TB,所以TB是一直在运行的,在TB0中断被禁止时TB0产生中断,则不会被响应,而开启TB0中断时人为清除了TB0中断标志,所以导致该次TB0中断不会被响应。从而TBCCR0不会被重新配置,使得TB0要在下一次等于TBCCR0时才能产生中断,而这个时间最大为2s。

解决方法:
在再次开启TB0中断时不应该人为清除TB0中断标志。因为这个中断是应该要响应的,只是在与24L01进行SPI通信时暂时被禁止。
一开始想要在禁止TB0中断时停止TB,这个思路是错误的,而且并没有针对问题的关键。一方面,TB是不应该被停止的,另一方面,导致2s左右没有采集地磁的真正原因是人为清除了TB0中断标志使得TBCCR0错过了一次配置。

ASCII字符5×7点阵

分享一份不错的ASCII字符5*7点阵。今天使用时遇到了一个非常郁闷的问题,显示小写字母时总是往后挪了一个字,花了好长时间,才找到原来是字符点阵中有一个注释 //\ ,因为 \ 在C语言中是续行符,所以导致把下一行点阵数据给注释掉了,哎,很是郁闷啊。

1
2
3
4
5
6
7
8
9
10
 // _ _ _ _ _
// 0|_|_|_|_|_|
// 1|_|_|_|_|_|
// 2|_|_|_|_|_|
// 3|_|_|_|_|_|
// 4|_|_|_|_|_|
// 5|_|_|_|_|_|
// 6|_|_|_|_|_|
// 7|_|_|_|_|_| BLANK
// 0 1 2 3 4

0x00,0x00,0x00,0x00,0x00, // SP
0x00,0x00,0x4F,0x00,0x00, // !
0x00,0x07,0x00,0x07,0x00, // ”
0x14,0x7F,0x14,0x7F,0x14, // #
0x24,0x2A,0x7F,0x2A,0x12, // $
0x23,0x13,0x08,0x64,0x62, // %
0x36,0x49,0x55,0x22,0x50, // &
0x00,0x05,0x03,0x00,0x00, // ‘
0x00,0x1C,0x22,0x41,0x00, // (
0x00,0x41,0x22,0x1C,0x00, // )
0x14,0x08,0x3E,0x08,0x14, // *
0x08,0x08,0x3E,0x08,0x08, // +
0x00,0x50,0x30,0x00,0x00, // ,
0x08,0x08,0x08,0x08,0x08, // –
0x00,0x60,0x60,0x00,0x00, // .
0x20,0x10,0x08,0x04,0x02, // /

0x3E,0x51,0x49,0x45,0x3E, // 0
0x00,0x42,0x7F,0x40,0x00, // 1
0x42,0x61,0x51,0x49,0x46, // 2
0x21,0x41,0x45,0x4B,0x31, // 3
0x18,0x14,0x12,0x7F,0x10, // 4
0x27,0x45,0x45,0x45,0x39, // 5
0x3C,0x4A,0x49,0x49,0x30, // 6
0x01,0x71,0x09,0x05,0x03, // 7
0x36,0x49,0x49,0x49,0x36, // 8
0x06,0x49,0x49,0x29,0x1E, // 9

0x00,0x36,0x36,0x00,0x00, // :
0x00,0x56,0x36,0x00,0x00, // ;
0x08,0x14,0x22,0x41,0x00, // < 0x14,0x14,0x14,0x14,0x14, // = 0x41,0x22,0x14,0x08,0x00, // >
0x02,0x01,0x51,0x09,0x06, // ?

0x32,0x49,0x79,0x41,0x3E, //@
0x7E,0x11,0x11,0x11,0x7E, //A
0x7F,0x49,0x49,0x49,0x36, //B
0x3E,0x41,0x41,0x41,0x22, //C
0x7F,0x41,0x41,0x22,0x1C, //D
0x7F,0x49,0x49,0x49,0x41, //E
0x7F,0x09,0x09,0x09,0x01, //F
0x3E,0x41,0x49,0x49,0x7A, //G
0x7F,0x08,0x08,0x08,0x7F, //H
0x00,0x41,0x7F,0x41,0x00, //I
0x20,0x40,0x41,0x3F,0x01, //J
0x7F,0x08,0x14,0x22,0x41, //K
0x7F,0x40,0x40,0x40,0x40, //L
0x7F,0x02,0x0C,0x02,0x7F, //M
0x7F,0x04,0x08,0x10,0x7F, //N
0x3E,0x41,0x41,0x41,0x3E, //O

0x7F,0x09,0x09,0x09,0x06, //P
0x3E,0x41,0x51,0x21,0x5E, //Q
0x7F,0x09,0x19,0x29,0x46, //R
0x46,0x49,0x49,0x49,0x31, //S
0x01,0x01,0x7F,0x01,0x01, //T
0x3F,0x40,0x40,0x40,0x3F, //U
0x1F,0x20,0x40,0x20,0x1F, //V
0x3F,0x40,0x38,0x40,0x3F, //W
0x63,0x14,0x08,0x14,0x63, //X
0x03,0x04,0x78,0x04,0x03, //Y
0x61,0x51,0x49,0x45,0x43, //Z

0x00,0x7F,0x41,0x41,0x00, //[
0x02,0x04,0x08,0x10,0x20, /*\*/
0x00,0x41,0x41,0x7F,0x00, //]
0x04,0x02,0x01,0x02,0x04, //^
0x40,0x40,0x40,0x40,0x40, //_

0x00,0x01,0x02,0x04,0x00, //`
0x20,0x54,0x54,0x54,0x78, //a
0x7F,0x48,0x44,0x44,0x38, //b
0x38,0x44,0x44,0x44,0x20, //c
0x38,0x44,0x44,0x48,0x7F, //d
0x38,0x54,0x54,0x54,0x18, //e
0x08,0x7E,0x09,0x01,0x02, //f
0x08,0x54,0x54,0x54,0x3C, //g
0x7F,0x08,0x04,0x04,0x78, //h
0x00,0x48,0x7D,0x40,0x00, //i
0x20,0x40,0x44,0x3D,0x00, //j
0x7F,0x10,0x28,0x44,0x00, //k
0x00,0x41,0x7F,0x40,0x00, //l
0x7C,0x04,0x78,0x04,0x78, //m
0x7C,0x08,0x04,0x04,0x78, //n
0x38,0x44,0x44,0x44,0x38, //o

0x7C,0x14,0x14,0x14,0x08, //p
0x08,0x14,0x14,0x18,0x7C, //q
0x7C,0x08,0x04,0x04,0x08, //r
0x48,0x54,0x54,0x54,0x20, //s
0x04,0x3F,0x44,0x40,0x20, //t
0x3C,0x40,0x40,0x20,0x7C, //u
0x1C,0x20,0x40,0x20,0x1C, //v
0x3C,0x40,0x30,0x40,0x3C, //w
0x44,0x28,0x10,0x28,0x44, //x
0x0C,0x50,0x50,0x50,0x3C, //y
0x44,0x64,0x54,0x4C,0x44, //z

0x00,0x08,0x36,0x41,0x00, //{
0x00,0x00,0x7F,0x00,0x00, //|
0x00,0x41,0x36,0x08,0x00, //}
0x10,0x08,0x08,0x10,0x08 //~

开漏输出与推挽输出

开漏输出:MOS管漏极开路。
要得到高电平需要上拉电阻才行。一般用于线或、线与,适合做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)。开漏是对MOS管而言,开集是对双极型管而言,在用法上没区别,开漏输出端相对于三极管的集电极。如果开漏引脚不连接外部的上拉电阻,则只能输出低电平。因此,对于经典的51单片机的P0口,要想做输入/输出功能必须加外部上拉电阻,否则无法输出高电平逻辑。一般来说,可以利用上拉电阻接不通的电压,改变传输电平,以连接不通电平(3.3V或5V)的器件或系统,这样就可以进行任意电平转换了。
漏极开路输出高电平本质就相当于IO口断开,直接被上拉电阻上拉;而输出低电平实际就是电流被IO口吸收。
推挽输出:
如果输出级的两个参数相同MOS管(或三极管)受两互补信号的控制,始终处于一个导通,一个截止状态,就是推挽项链,这种结构称为推拉式电路。推挽输出电路输出高电平或低电平时,两个MOS管交替工作,可以减低功耗,并提高每个管的承受能力。又由于不论走那条路,管制导通电阻都很小,使RC常数很小,逻辑电平转变速度很快,因此,推拉式输出既可以提高电路的负载能力,又能提高开关速度,且导通损耗小效率高。输出既可以向负载灌电流(作为输出),也可以从负载抽取电流(作为输入)。

晶振和晶振电容

如何选择晶振
对于一个高可靠性系统,晶振的选择非常重要,尤其是设计带有睡眠功唤醒(往往用低电压以求低功耗)的系统。这是因为低供电电压是提供给晶振的激励公路减少,造成晶振起振很慢或根本就不起振。这一现象在上电复位时并不特别明显,原因是上电时电路有足够的扰动,很容易建立正当。在睡眠唤醒时,电路的扰动要比上电时小得多,起振变得很不容易。
在振荡回路中,晶振既不能过激励(容易振到高次谐波上),也不能前激励(不容易起振)。
晶振的选择至少必须考虑谐振点、负载电容、激励功率、温度特性、长期稳定性。

如何选择晶振电容
(1)因为每种晶振都有各自特性,所以最好按芯片制造厂商提供的数值选择外部器件。
(2)电容值小,容易起振;但过低,振荡器容易不稳定。电容值大,有利于振荡器的稳定,但过大,会增加起振时间,不容易起振。
以上内容摘自《基于ARM Cortex-M3的STM32系列嵌入式微控器应用实践》

STM32上电默认是使用内部高速RC时钟(HIS),因此,用示波器检查OSC引脚是否有时钟信号来判断STM32单片机最小系统是否工作是错误的。

STM32单片机RTC使用的低速晶振要求比较苛刻,需要使用负载电容为6pF的晶振,而最常见的32.768kHz晶振负载电容为12.5pF。ST数据手册上特别强调了这一点。据说使用常规晶振有10%的死机可能。

第 20 页,共 50 页« 最新...10...1819202122...304050...最旧 »