1.定时器的工作原理
注意当TCNTn=TCMPn时不会产生中断。
2.代码
2.1 timer.c
首先是根据上面的两个寄存器设置时钟;
/* 设置TIMER0的时钟 */
/* Timer clk = PCLK / {prescaler value+1} / {divider value}
= 50000000/(99+1)/16
= 31250
*/
TCFG0 = 99; /* Prescaler 0 = 99, 用于timer0,1 */
TCFG1 &= ~0xf;
TCFG1 |= 3; /* MUX0 : 1/16 */
然后根据上图的寄存器设置初始值。
/* 设置TIMER0的初值 */
TCNTB0 = 15625; /* 0.5s中断一次 */
然后根据上面的寄存器设置加载初值。
/* 加载初值, 启动timer0 */
TCON |= (1<<1); /* Update from TCNTB0 & TCMPB0 */
然后还是根据上图的寄存器,设置为自动加载并启动。
/* 设置为自动加载并启动 */
TCON &= ~(1<<1);
TCON |= (1<<0) | (1<<3); /* bit0: start, bit3: auto reload */
然后我们实现定时器中断处理函数,在里面循环点灯。
void timer_irq(void)
{
/* 点灯计数 */
static int cnt = 0;
int tmp;
cnt++;
tmp = ~cnt;
tmp &= 7;
GPFDAT &= ~(7<<4);
GPFDAT |= (tmp<<4);
}
完整的timer.c如下
#include "s3c2440_soc.h"
void timer_init(void)
{
/* 设置TIMER0的时钟 */
/* Timer clk = PCLK / {prescaler value+1} / {divider value}
= 50000000/(99+1)/16
= 31250
*/
TCFG0 = 99; /* Prescaler 0 = 99, 用于timer0,1 */
TCFG1 &= ~0xf;
TCFG1 |= 3; /* MUX0 : 1/16 */
/* 设置TIMER0的初值 */
TCNTB0 = 15625; /* 0.5s中断一次 */
/* 加载初值, 启动timer0 */
TCON |= (1<<1); /* Update from TCNTB0 & TCMPB0 */
/* 设置为自动加载并启动 */
TCON &= ~(1<<1);
TCON |= (1<<0) | (1<<3); /* bit0: start, bit3: auto reload */
/* 设置中断 */
}
void timer_irq(void)
{
/* 点灯计数 */
static int cnt = 0;
int tmp;
cnt++;
tmp = ~cnt;
tmp &= 7;
GPFDAT &= ~(7<<4);
GPFDAT |= (tmp<<4);
}
2.2 interrupt.c
然后还要设置中断控制器,开启定时器中断。
#include "s3c2440_soc.h"
/* SRCPND 用来显示哪个中断产生了, 需要清除对应位
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTMSK 用来屏蔽中断, 1-masked
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTPND 用来显示当前优先级最高的、正在发生的中断, 需要清除对应位
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTOFFSET : 用来显示INTPND中哪一位被设置为1
*/
/* 初始化中断控制器 */
void interrupt_init(void)
{
INTMSK &= ~((1<<0) | (1<<2) | (1<<5));
INTMSK &= ~(1<<10); /* enable timer0 int */
}
/* 初始化按键, 设为中断源 */
void key_eint_init(void)
{
/* 配置GPIO为中断引脚 */
GPFCON &= ~((3<<0) | (3<<4));
GPFCON |= ((2<<0) | (2<<4)); /* S2,S3被配置为中断引脚 */
GPGCON &= ~((3<<6) | (3<<22));
GPGCON |= ((2<<6) | (2<<22)); /* S4,S5被配置为中断引脚 */
/* 设置中断触发方式: 双边沿触发 */
EXTINT0 |= (7<<0) | (7<<8); /* S2,S3 */
EXTINT1 |= (7<<12); /* S4 */
EXTINT2 |= (7<<12); /* S5 */
/* 设置EINTMASK使能eint11,19 */
EINTMASK &= ~((1<<11) | (1<<19));
}
/* 读EINTPEND分辨率哪个EINT产生(eint4~23)
* 清除中断时, 写EINTPEND的相应位
*/
void key_eint_irq(int irq)
{
unsigned int val = EINTPEND;
unsigned int val1 = GPFDAT;
unsigned int val2 = GPGDAT;
if (irq == 0) /* eint0 : s2 控制 D12 */
{
if (val1 & (1<<0)) /* s2 --> gpf6 */
{
/* 松开 */
GPFDAT |= (1<<6);
}
else
{
/* 按下 */
GPFDAT &= ~(1<<6);
}
}
else if (irq == 2) /* eint2 : s3 控制 D11 */
{
if (val1 & (1<<2)) /* s3 --> gpf5 */
{
/* 松开 */
GPFDAT |= (1<<5);
}
else
{
/* 按下 */
GPFDAT &= ~(1<<5);
}
}
else if (irq == 5) /* eint8_23, eint11--s4 控制 D10, eint19---s5 控制所有LED */
{
if (val & (1<<11)) /* eint11 */
{
if (val2 & (1<<3)) /* s4 --> gpf4 */
{
/* 松开 */
GPFDAT |= (1<<4);
}
else
{
/* 按下 */
GPFDAT &= ~(1<<4);
}
}
else if (val & (1<<19)) /* eint19 */
{
if (val2 & (1<<11))
{
/* 松开 */
/* 熄灭所有LED */
GPFDAT |= ((1<<4) | (1<<5) | (1<<6));
}
else
{
/* 按下: 点亮所有LED */
GPFDAT &= ~((1<<4) | (1<<5) | (1<<6));
}
}
}
EINTPEND = val;
}
void handle_irq_c(void)
{
/* 分辨中断源 */
int bit = INTOFFSET;
/* 调用对应的处理函数 */
if (bit == 0 || bit == 2 || bit == 5) /* eint0,2,eint8_23 */
{
key_eint_irq(bit); /* 处理中断, 清中断源EINTPEND */
}
else if (bit == 10)
{
timer_irq();
}
/* 清中断 : 从源头开始清 */
SRCPND = (1< } 3. 代码改进 上面的代码我们可以看到,当我们添加了定时器中断之后,我们要在interrupt.c里面重新添加定时器中断相关的配置,那么如果我们以后再添加别的中断,那么还要再修改interrupt.c,太麻烦了,下面我们用函数指针数组改进代码。 我们首先定义一个数组,用来保存中断处理函数的指针。 typedef void(*irq_func)(int); irq_func irq_array[32]; 然后我们实现一个注册函数,在这个注册函数里面把中断处理函数存到数组里面,并且使能中断。 void register_irq(int irq, irq_func fp) { irq_array[irq] = fp; INTMSK &= ~(1< 3.1 优化后的interrupt.c #include "s3c2440_soc.h" typedef void(*irq_func)(int); irq_func irq_array[32]; /* SRCPND 用来显示哪个中断产生了, 需要清除对应位 * bit0-eint0 * bit2-eint2 * bit5-eint8_23 */ /* INTMSK 用来屏蔽中断, 1-masked * bit0-eint0 * bit2-eint2 * bit5-eint8_23 */ /* INTPND 用来显示当前优先级最高的、正在发生的中断, 需要清除对应位 * bit0-eint0 * bit2-eint2 * bit5-eint8_23 */ /* INTOFFSET : 用来显示INTPND中哪一位被设置为1 */ /* 初始化中断控制器 */ void interrupt_init(void) { INTMSK &= ~((1<<0) | (1<<2) | (1<<5)); INTMSK &= ~(1<<10); /* enable timer0 int */ } /* 读EINTPEND分辨率哪个EINT产生(eint4~23) * 清除中断时, 写EINTPEND的相应位 */ void key_eint_irq(int irq) { unsigned int val = EINTPEND; unsigned int val1 = GPFDAT; unsigned int val2 = GPGDAT; if (irq == 0) /* eint0 : s2 控制 D12 */ { if (val1 & (1<<0)) /* s2 --> gpf6 */ { /* 松开 */ GPFDAT |= (1<<6); } else { /* 按下 */ GPFDAT &= ~(1<<6); } } else if (irq == 2) /* eint2 : s3 控制 D11 */ { if (val1 & (1<<2)) /* s3 --> gpf5 */ { /* 松开 */ GPFDAT |= (1<<5); } else { /* 按下 */ GPFDAT &= ~(1<<5); } } else if (irq == 5) /* eint8_23, eint11--s4 控制 D10, eint19---s5 控制所有LED */ { if (val & (1<<11)) /* eint11 */ { if (val2 & (1<<3)) /* s4 --> gpf4 */ { /* 松开 */ GPFDAT |= (1<<4); } else { /* 按下 */ GPFDAT &= ~(1<<4); } } else if (val & (1<<19)) /* eint19 */ { if (val2 & (1<<11)) { /* 松开 */ /* 熄灭所有LED */ GPFDAT |= ((1<<4) | (1<<5) | (1<<6)); } else { /* 按下: 点亮所有LED */ GPFDAT &= ~((1<<4) | (1<<5) | (1<<6)); } } } EINTPEND = val; } void handle_irq_c(void) { /* 分辨中断源 */ int bit = INTOFFSET; /* 调用对应的处理函数 */ irq_array[bit](bit); /* 清中断 : 从源头开始清 */ SRCPND = (1< } void register_irq(int irq, irq_func fp) { irq_array[irq] = fp; INTMSK &= ~(1< /* 初始化按键, 设为中断源 */ void key_eint_init(void) { /* 配置GPIO为中断引脚 */ GPFCON &= ~((3<<0) | (3<<4)); GPFCON |= ((2<<0) | (2<<4)); /* S2,S3被配置为中断引脚 */ GPGCON &= ~((3<<6) | (3<<22)); GPGCON |= ((2<<6) | (2<<22)); /* S4,S5被配置为中断引脚 */ /* 设置中断触发方式: 双边沿触发 */ EXTINT0 |= (7<<0) | (7<<8); /* S2,S3 */ EXTINT1 |= (7<<12); /* S4 */ EXTINT2 |= (7<<12); /* S5 */ /* 设置EINTMASK使能eint11,19 */ EINTMASK &= ~((1<<11) | (1<<19)); register_irq(0, key_eint_irq); register_irq(2, key_eint_irq); register_irq(5, key_eint_irq); } 3.2 优化后的timer.c #include "s3c2440_soc.h" void timer_irq(void) { /* 点灯计数 */ static int cnt = 0; int tmp; cnt++; tmp = ~cnt; tmp &= 7; GPFDAT &= ~(7<<4); GPFDAT |= (tmp<<4); } void timer_init(void) { /* 设置TIMER0的时钟 */ /* Timer clk = PCLK / {prescaler value+1} / {divider value} = 50000000/(99+1)/16 = 31250 */ TCFG0 = 99; /* Prescaler 0 = 99, 用于timer0,1 */ TCFG1 &= ~0xf; TCFG1 |= 3; /* MUX0 : 1/16 */ /* 设置TIMER0的初值 */ TCNTB0 = 15625; /* 0.5s中断一次 */ /* 加载初值, 启动timer0 */ TCON |= (1<<1); /* Update from TCNTB0 & TCMPB0 */ /* 设置为自动加载并启动 */ TCON &= ~(1<<1); TCON |= (1<<0) | (1<<3); /* bit0: start, bit3: auto reload */ /* 设置中断 */ register_irq(10, timer_irq); }
上一篇:S3C2440裸机------Nor Flash原理及硬件操作
下一篇:S3C2440裸机------异常与中断__swi异常模示程序示例
推荐阅读
史海拾趣
Hanghsing Enterprise Co., Ltd. 的五个发展故事
故事一:初创与起步
Hanghsing Enterprise Co., Ltd.(以下简称“Hanghsing”)成立于台湾,起初是一家专注于精密零部件制造的小型公司。公司位于No. 1, Lane 39, Seuwe St., Tali City, Taichung Hsien, Taiwan 412,凭借对品质的不懈追求和对市场的敏锐洞察,Hanghsing逐渐在行业内崭露头角。公司初期主要生产Valve Shafts、Nuts、Screws等精密不锈钢部件,这些产品广泛应用于电子、机械等多个领域。通过不断优化生产工艺和质量控制体系,Hanghsing逐渐建立了良好的市场口碑。
故事二:技术突破与产品升级
随着电子行业的快速发展,Hanghsing意识到技术创新的重要性。公司加大了对研发的投入,引进了一批高素质的技术人才,致力于新产品的开发和现有产品的升级。经过不懈努力,Hanghsing成功推出了一系列高精度、高可靠性的电子产品零部件,如Sleeve Barrels、Toggles和Mandrels等。这些产品不仅满足了市场对高品质零部件的需求,还进一步巩固了公司在电子行业供应链中的地位。
故事三:市场拓展与国际合作
随着产品质量的不断提升和市场份额的逐步扩大,Hanghsing开始将目光投向国际市场。公司积极参加各类国际展会,与全球知名电子企业建立合作关系,将产品销往世界各地。同时,Hanghsing还注重与国际技术标准的接轨,确保产品符合国际市场的严格要求。通过不断的市场拓展和国际合作,Hanghsing在国际上的知名度和影响力得到了显著提升。
故事四:产业升级与多元化发展
面对电子行业的快速发展和市场竞争的日益激烈,Hanghsing积极寻求产业升级和多元化发展的路径。公司开始涉足电子元器件的制造和研发领域,通过引进先进的生产设备和工艺技术,不断提升产品的附加值和市场竞争力。同时,Hanghsing还积极拓展上下游产业链,与原材料供应商和终端客户建立紧密的合作关系,形成了完整的产业生态体系。
故事五:绿色生产与可持续发展
在追求经济效益的同时,Hanghsing始终不忘履行社会责任。公司积极响应国家环保政策,致力于绿色生产和可持续发展。通过引进环保设备和工艺技术,减少生产过程中的污染物排放和资源消耗。同时,Hanghsing还加强了对员工的环保教育和培训,提高员工的环保意识和责任感。这些举措不仅有助于提升公司的社会形象和市场竞争力,还为推动电子行业的绿色发展做出了积极贡献。
首先,需要澄清的是,直接关于“General Electric Solid State”公司的发展故事在现有的参考资料中并不详尽,因为“General Electric Solid State”可能并不是一个独立的公司名称,而是指通用电气公司(General Electric Company,简称GE)在固态技术或固态电子领域的业务或产品部门。以下是根据通用电气公司在电子行业,特别是固态技术领域的发展历程,提炼出的五个相关故事:
1. 固态技术的早期探索
背景:在20世纪中后期,随着半导体技术的飞速发展,通用电气公司(GE)作为电气行业的领导者,迅速投入到了固态技术的研发中。这一时期,GE的工程师们致力于开发更高效的固态器件,如晶体管、集成电路等,以替代传统的电子管设备。
发展:GE的研究团队在固态材料的选择、制造工艺的优化以及性能提升方面取得了显著进展。这些成果不仅推动了GE自身产品的升级换代,也为整个电子行业向固态化、集成化方向发展奠定了基础。
2. 固态器件在电力系统中的应用
背景:电力系统是GE的传统优势领域之一。随着固态技术的成熟,GE开始将固态器件应用于电力系统中,以提高电力系统的效率和可靠性。
应用:GE研发了一系列基于固态技术的电力电子设备,如固态继电器、固态断路器、固态变压器等。这些设备在电力系统中扮演着重要角色,能够有效减少能源损耗、提高电力传输效率,并增强电力系统的稳定性和安全性。
3. 固态照明技术的突破
背景:通用电气公司的创始人托马斯·爱迪生因发明电灯而闻名于世。进入21世纪后,GE继续在照明领域深耕,将固态技术应用于照明产品中。
成果:GE成功推出了LED(发光二极管)照明产品,这些产品具有能效高、寿命长、环保等优点。GE的LED照明技术不仅应用于家庭和商业照明领域,还广泛应用于户外照明、工业照明等多个场景,为全球节能减排事业做出了贡献。
4. 固态传感器与工业自动化
背景:随着工业自动化水平的不断提高,对传感器的精度、稳定性和可靠性提出了更高的要求。GE凭借其在固态技术方面的积累,开始研发高性能的固态传感器。
应用:GE的固态传感器在工业自动化领域得到了广泛应用,如温度传感器、压力传感器、加速度传感器等。这些传感器能够实时监测设备的运行状态和环境参数,为工业自动化控制提供精准的数据支持。
5. 固态技术在医疗设备中的创新
背景:医疗设备对技术的要求极高,尤其是在精确性和可靠性方面。GE作为医疗设备领域的领军企业之一,不断将固态技术引入医疗设备的研发中。
创新:GE利用固态技术开发出了一系列创新的医疗设备,如固态成像设备(如CT、MRI等)、固态激光治疗器等。这些设备在医疗诊断、治疗等方面发挥了重要作用,提高了医疗服务的效率和质量。
请注意,以上故事是基于通用电气公司在电子行业,特别是固态技术领域的整体发展历程进行提炼的。由于“General Electric Solid State”并非一个明确的公司名称,因此故事中的具体细节可能需要根据GE的实际情况进行适当调整和补充。
除了商业产品的研发外,西安航天民芯还积极承担国家重大科研项目。公司参与了我国工业强基高性能工业DSP芯片等多项国产化项目的研发工作,为提升国家产业核心竞争力做出了贡献。这些项目的成功实施,进一步提升了西安航天民芯在行业内的影响力和地位。
随着电子产品的普及和消费者对产品质量的关注,电子产品测试和认证成为了一个必不可少的环节。BSI作为全球知名的认证机构,为电子产品提供了专业的测试和认证服务。通过严格的测试和认证流程,BSI确保了电子产品符合国际标准和客户需求,提高了产品的市场竞争力和信誉度。同时,BSI还为企业提供了定制化的商检解决方案,帮助企业在国际贸易中解决技术和法规问题,降低了贸易风险。
Brand-Rex的综合布线产品在国家重大项目上得到了广泛应用。例如,昌北国际机场作为中国干线机场,其总建筑面积达到96616平方米。该项目于2010年9月中标,2011年5月22日竣工并投入使用。整个系统均采用了Brand-Rex的CAT6PLUS全系列铜缆和光纤产品,充分展示了Brand-Rex在大型项目中的技术实力和产品可靠性。此外,Brand-Rex还参与了其他多个重要项目的布线工作,为国家基础设施的建设做出了积极贡献。
随着科技的进步,客户对电子元器件的性能要求也越来越高。CalRamic Technologies意识到,要想在激烈的市场竞争中脱颖而出,必须不断进行技术创新。因此,公司投入大量资源进行产品研发,特别是在陶瓷电容器领域取得了显著的技术突破。他们开发的新型陶瓷电容器不仅体积更小,性能也更加稳定,很快就受到了市场的热烈欢迎。
6月23日至25嵌入式手机游戏及应用开发零起点零基础基础免费课程 时间:6月23日至25日 每晚(19:30分-21:30分) 课程:嵌入式手机游戏及应用开发零起点零基础免费课程 每日预计用时2小时,中间休息15分钟(请直接与咨询师联系索取免 ...… 查看全部问答∨ |
|
利用CMGR或者CMGL的AT命令读取短信时,经常收到内容之后,OK接收不完整。有时能够收到正常的,有时又无法收到,或只收到部分,导致对其没办法处理。因为我是在收到OK后再进行处理的,谁能够帮我看看是什么方面的原因,谢谢了? 注:我在程序中用过 ...… 查看全部问答∨ |
请问各位大侠,我在调试应用程序时,使用单步跟踪的方式,为什么每次执行完uglOSTaskCreate();后,再单步跟,就跳出来汇编界面?即使我在主函数中设置了断点也跟不进去主函数,但我的科学试验的运行结果是正确的,请各位大侠不吝指教!具体入口函数 ...… 查看全部问答∨ |
哪个有现成的直流电流采样电路不???几十微安到几十毫安,,送单片机的AD里面的 哪个有现成的直流电流采样电路不???几十微安到几十毫安,,送单片机的AD里面的 哪个有现成的直流电流采样电路不???几十微安到几十毫安,,送单片机的AD里面的… 查看全部问答∨ |
打破通信巨头制定价格现状的基础设施和气候条件已经形成,洗牌的机会应当来自于我们十分熟悉的WIFI技术。大家一定要问,WIFI已经存在这么多年了,它有什么新鲜和特别之处。 事先要声明的是,这只是我的直觉,当然这个知觉也不一定对,不过有些证 ...… 查看全部问答∨ |