tag 标签: c语言培训

相关博文
  • 热度 29
    2012-6-19 22:16
    3304 次阅读|
    1 个评论
    兴趣是学习一切东西的原动力!本人认为,在小时候要多参加一些培训,为什么呢,因为自己,你的父母亲,老师,很难发现你的真正兴趣所在,以至于到了高中毕业填志愿稀里糊涂的填了志愿,等到读完大二,才知道本专业自己原来不喜欢!下面这篇文档是我的学生写的,他是纺织专业,现在是大三,一个班8个学生,记得有一次有一个程序只有他能写出来,其他7个,有自动化的,有通信的!他是真正找到了他的兴趣所在,所以他乐此不疲!       下面的这篇是我要求他写的一个技术文档,虽然前人写过,但是我要求他比别人写的更仔细一点,更完整一点!我现在在带他做项目,希望后面能看到他更有价值的原创东西! ================================================================= 作者:Jakawn Rada(索漫科技arm就业班学员) ? 如何测定数码管是共阴? ? 如何测定数码管是共阳? 如何测定数码管是共阴? 我们先看数码管的结构图(以标准7 段LED 数码管为例)       以上是单个的数码管,A-G 的每一个字母表示的段称为Segment 下面是常见的数码管实物图(有四个DIGITALS) 它的引脚图如下:     测试步骤:(如果只要判定数码管是共阴的则只需要做到第二步就可以了) 1 先准备好测试工具:先找到5V 电源,引出正极,然后必须 接上200K 的电阻(防止电流过大,烧坏数码管)。示意图如下:   2 如果上一步中的测试电源B 端接在SEG1 引脚上(说明我们 当前选定了第一个数码管,从左数起),A 端接在a-f 中的任意一个引 脚,这时SEG1对应的段亮了则说明是共阴的。 3 重复第二步,可以测试SEG1 中的所有段是否可以正常显示, 例如A 端接在a 引脚则a 段会显示亮,接在b 引脚则b 段会亮等。 4 重复第二步,但是电源B 端接在SEG2 引脚上(说明我们当 前选定了第二个数码管,从左数起),A 端接在a-f 中的任意一个引脚, 这时SEG2 对应的段亮了则说明相应LED 段是可以正常显示的。 5 重复第四步可以接着测试SEG3 和SEG4 的每一个段是否可 以正常显示,以判定所使用的数码是否是好的。 如何测定数码管是共阳? 步骤和测定共阴的时候一样,只是这时换成电源A端接在SEG1-4 中的一个引脚,电源B端接在a-f中的一个引脚就可以了。 Jakawn Rada 2012-5-30 【上海索漫科技提供】  
  • 热度 15
    2012-6-19 22:03
    2512 次阅读|
    0 个评论
    原创作品,转载请注明 作者:潇湘- ,自动化大三 (索漫科技linux驱动班学员) 一、目的        在LPC2136下,研究IOPIN置高电平与IOSET置高电平的区别。 二、缘由        在一系列实验时我发现,IOPIN寄存器在IODIR寄存器设置好方向后,也能实现输入和输出高低电平。和IOSET有所区别的是IOSET置高电平后要用IOCLR清除,而IOPIN只需要在变量赋值时重新覆盖即可。 三、实验过程 大家可以用小灯程序做个实验 在我的开发板中小灯的引脚如下图所示 故做如下实验 用IOPIN寄存器时 #define LED1  116 #define LED2  117 #define LED3  118 #define LED4  119 /**************************************************************************** * 名称:initSystem() * 功能:初始化IO ****************************************************************************/ void initSystem(void) {       IO1DIR = LED1|LED2|LED3|LED4;//设置方向       IO1SET = LED1|LED2|LED3|LED4 ;//高电平使灯灭 }          /**************************************************************************** * 名称:main() * 功能:初始化led,并实现led4闪烁的效果。 ****************************************************************************/ int main(void) {       initSystem();        while(1)     {               IO1PIN = LED1|LED2|LED3  ;//123灯灭,4灯亮        delay(40);        IO1PIN = LED1|LED2|LED3|LED4 ;//1234灯全灭       delay(40);     }       return 0; }        由此可见,用IOXPIN寄存器时发现LED4在闪烁,说明当把变量赋给IOXPIN寄存器时可以刷新 用IOSET寄存器时 int main(void) {       initSystem();        while(1)      {             IO1SET = LED1|LED2|LED3;         delay(40);          IO1SET= LED1|LED2|LED3|LED4 ;        delay(40);   }       return 0; } 发现LED4灯没有闪烁,说明IOXSET寄存器必须要IOCLR置一才能消去高电平。   下面请看数据手册中IOSET和IOCLR的解释     四、思考         数据手册告诉了我们。但是我发现IOPIN寄存器不只个状态寄存器,它也有别样的功能。程序在一定程度上可以简化,原来程序中,IOSET和IOCLR需要一起作用,如今只需要IOPIN一个寄存器就能解决了。 2012年6月19日                                              写于上海.松江             
  • 热度 21
    2012-4-4 12:31
    3522 次阅读|
    1 个评论
    ARM7中断原理的最基本部分与单片机是一样的,如果对单片机中断原理比较熟悉,再来理解ARM7的中断原理是顺理成章的事情。 1.中断向量表 下面以Philips的lpc2136为例进行比较深入的分析: 我们在用ads1.2调试开发板时,有一个startup.s的汇编程序,这个程序就是lpc2136得以运行的启动代码,是及其重要的一部分,蕴含着ARM7的精髓。 其中,有这样一段代码: AREA vectors,CODE,READONLY ENTRY ;interrupt vectors ;中断向量表 Vector_Init_Block LDR PC, Reset_Addr LDR PC, Undefined_Addr LDR PC, SWI_Addr LDR PC, Prefetch_Addr LDR PC, Abort_Addr DCD 0xb9205f80 LDR PC, LDR PC, FIQ_Addr Reset_Addr DCD Start_Boot Undefined_Addr DCD Undefined_Handler SWI_Addr DCD SWI_Handler Prefetch_Addr DCD Prefetch_Handler Abort_Addr DCD Abort_Handler Nouse DCD 0 IRQ_Addr DCD 0 FIQ_Addr DCD FIQ_Handler ;未定义指令 Undefined_Handler B Undefined_Handler ;软中断 SWI_Handler B SWI_Handler ;取指令中止 Prefetch_Handler B Prefetch_Handler ;取数据中止 Abort_Handler B Abort_Handler ;快速中断 FIQ_Handler STMFD SP!, {R0-R3, LR} BL FIQ_Exception LDMFD SP!, {R0-R3, LR} SUBS PC, LR, #4 下面的这个截图来自ads1.2安装后的“online book”里面(这里面有很多非常重要的知识,你不懂的任何疑问都可以在此找到答案,可惜很多人不知道这个好地方)   ARM体系设计有八种异常,并把所有现象用异常来表达,我们的代码任何时刻都在这八种异常中运行。 我们给开发板上电,这就是一种“异常”,这种异常用”Reset”来表示。 这八种异常对应八个地址: Reset(复位)=========0x00000000(当上电,或按下开发板的复位键时,程序跳到该地址运行) Undef(未定义指令)=========0x00000004(当程序指针访问地址出现未定义指令,程序跳到该地址运行) SWI(软件中断)=========0x00000008(当发生软件中断,程序跳到该地址运行) Prefetch Abort(预取指中止)=========0x0000000C(当预取值失败,程序跳到该地址运行) Data Abort(数据中止)=========0x00000010(当访问数据区失败,程序跳到该地址运行) Reserved(保留)===========0x00000014 IRQ===========0x00000018(当发生IRQ中断时,程序跳到该地址运行) FIQ(快速中断)========0x0000001C(当发生快速中断时,程序跳到该地址运行) 2 FIQ中断,向量IRQ,非向量IRQ区别 FIQ是指快速中断请求(Fast Interrupt reQuest),具有最高优先级,一般只声明一个中断源为FIQ,这样可以得到最快的相应速度,如果非要申请多个中断源为FIQ,那么当中断发生时,FIQ中断线程通过读取FIQ状态寄存器来判断当前发生的是那个中断。 向量IRQ(Vector IRQ)是指向量中断请求(Vector Interrupt ReQuest)。具有次高优先级。 非向量IRQ(NO_Vector IRQ)是指非向量中断请求。具有最低优先级。 (未完待续)
  • 热度 25
    2012-4-4 12:27
    2177 次阅读|
    5 个评论
    802..15.4(zigbee 协议) 作者:下家山 一:802.15.4帧格式       图一   1.1 Preamble Sequence 此字段包含4个字节,有cc2420自动产生。 1.2 Start of Frame Delimiter 此字段包含1个字节,有cc2420自动产生。    ============================================================================= 1.3 Mac Protocol Data Unit          接下来的字段是我们需要设置的 二:结构体表示MPDU 通常我们用一个结构体来表示 typedef struct {   /* The following fields are transmitted/received on the radio. */   char length;   char fcfhi;   char fcflo;   char dsn;   int destpan;   int addr;   char type;   char group;   char Txdata ;     /* The following fields are not actually transmitted or received    * on the radio! They are used for internal accounting only.    * The reason they are in this structure is that the AM interface    * requires them to be part of the TOS_Msg that is passed to    * send/receive operations.    */   char strength;   char lqi;   int crc;   int ack;   int time;// } Msg; 如果,我们要发送一个字节0x55,程序该怎么写: #define CC2420_DEF_FCF_LO          0x08 #define TOS_BCAST_ADDR             0xffff #define CC2420_DEF_FCF_HI_ACK      0x21  // with ACK #define CC2420_DEF_FCF_HI          0x01  // without ACK void main() {    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT  hardwareinit();  Msg * data;  long int i,j;  data=(Msg*)malloc(sizeof(Msg));    P5DIR|=0X70;//0111 0000 1out 0 in  P5OUT|=0X70; //1高电平                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            data - length = 12;  //msg data length:10   last lqirssi:2  data - fcflo = CC2420_DEF_FCF_LO;//destination address mode:10  data - fcfhi = CC2420_DEF_FCF_HI_ACK;//ack request:1 frame type:10 // destination PAN is broadcast  data - destpan = TOS_BCAST_ADDR;  // adjust the destination address to be in the right byte order  data - addr = 0x0001;  // adjust the data type if need  data - type = FRAME_TYPE_DATA;  // keep the DSN increasing for ACK recognition  data - dsn = 1;  // reset the time field  data - time = 0; data - group=0x00; data - Txdata =0x55;   for(i=0;i100;i++) {  data-dsn =i;   sendAMessage(data - length,(char*)data);  for(j=0;j50000;j++); } free(data); P5OUT|=0X10; } 2.1发送数据截图 那么最终发送出去的数据是:                                                  图二 有了这些,我们可以把协议与代码,还有实际发送的数据一一对应起来 2.2 代码与发送数据汇总   2.3接收数据截图   那么接收到的数据呢? 首先,我们把发送与接收的数据的截图做一个比较: 三:怎么找到RSSI 那么我们MODEMCTRL0,AUTOCRC有没有被置位呢?                                                                         2010-10-18 11:06  写于上海.松江  (请尊重原创,转载请注明:作者,下家山)        
  • 热度 28
    2012-4-4 12:26
    2104 次阅读|
    0 个评论
    作者,下家山 9.1需要改动的地方 :        ①c/src/lib/libcpu/arm/s3c2410/include/s3c2400.h相应register的修改.        ②因为要使用串口功能,所以需要在应用程序中添加端口初始化函数,来初始化各端口,主要初始化Port F,H,端口F为LED显示功能所用,端口H为串口打印功能所用.            (可以直接复制s3c2410开发板套件资料的armsys_2410/hardware_test_pro中的Port_Init函数)        ③在c/src/lib/libbsp/arm/gp32/startup/Bspstart.c,bsp_start_default函数中添加bank0-bank7的相关register的设置        ④在start.S(见c/src/lib/libbsp/arm/gp32/start)中添加LED显示子程序.    9.2需要确认的地方:        ①在c/src/lib/libbsp/arm/gp32/console/Uart.c中对照s3c2410 datasheet确信各register地址是否正确.        ②确信baudrate是否与PC机上的串口baudrate一致.        ③Fclk,Pclk,Hclk的值为多少,相关函数参照c/src/lib/libcpu/arm/s3c2400/clock/Support.c c/src/lib/libbsp/arm/gp32/include/Bsp.h  c/src/lib/libbsp/arm/gp32/startup/Bspstart.c 知道baudrate,Fclk,Pclk,Hclk是怎么计算的,并对照s3c2410 datasheet确信计算结果是否准确.     9.3调试方法 :            LED跟踪(并借助ads)             所以需要写一个LED显示程序,最好用汇编写,并在ads上验证该程序能正常调用. 10:调试hello world时碰到的问题          我用LED一直跟踪到boot_card函数都很顺利,但到执行 BSP_RTEMS_Configuration = *Configuration.RTEMS_api_configuration;这条语句时程序跳飞。显然,这条跳飞的原因大半是指针造成的,Configuration.RTEMS_api_configuration是一个指针,使用指针的大忌是不初始化就使用,因为没有初始化,所指向的地址未知,因此程序跑飞.所以,我定义了一个rtems_api_configuration_table     结构体,并把其地址赋给Configuration.RTEMS_api_configuration,果然BSP_RTEMS_Configuration = *Configuration.RTEMS_api_configuration;执行过去了.我开始接着往下调,但一个OS往往是牵一发而动全身,改动了Configuration.RTEMS_api_configuration,接下来很多地方都要改动,所以要找到根源.           BSP_RTEMS_Configuration是Configuration的一个复制体,而Configuration是在confdefs.h中定义的,是一个已初始化的全局变量,所以我怀疑是不是全局变量初始化不成功?初始化的全局变量是放在.data区域的,而这一区域是定位在sdram中的.那么怎样才能看到这一区域的内容呢?最后想到了ads,我通过ftp把编译好的bin文件下载到板子后,再通过AXD调试软件查看sdram中的内容.这里,可以定义些一眼就能看出来的特征值,比如定义两个全局变量int a=0xaaaaaaaa;int b=0xbbbbbbbb;.但是,64M的sdram怎么查呢!用过ads的人应该知道,编译后的执行文件(.o)对每个函数,全局变量都已分配好了地址,这些地址在编译完成时在Section Cross References中会列出来.那么,在gcc中编译后怎么查看其中的函数,变量的地址呢?找相关资料,发现readelf就是干这个事的,所以readelf -a helloworld.exe map得到map文件,用UltraEdit -32打开查看,记下全局变量a,b的地址(map中你还可以看到各函数的具体位置及占用空间的大小。要知道自己添加的文件是否编译进去,这是个很好的方法,我在编译network时,就如此).然后,在axd中定位到刚才记下的地址,发现AXD中a,b的地址与刚记下的地址(map)相差0x100偏移量.后面,我还做了大量的实验,比如定义结构体.都证明gcc编译后的全局变量的地址与AXD中查到的地址相差0x100,AXD查到的地址应该是sdram中的实际反映.因此我马上想到了linkcmds文件的.base段,其定义的就是sdram起始的0x100个字节,果然,当我把.base段去掉后原来跑飞的地方通过了.但去掉.base也不是办法,之后把它移到.bss段。但后来想来想去还是不妥,既然系统把它定义到前面一定不会错,我把它改动了,还不知有什么后患呢?那还有什么办法呢?后来突然想到,我通过uboot下载bin文件到sdram时,load地址是0x30000000,我把load地址改为0x30000100后,也一样解决了问题.         在调试hello world例程时碰到的主要是这个问题.其他地方只要调试时细心应该不会有什么问题. 11:调试网络时碰到的问题            在testsuites/samples中找到loopback例程,发现要用到clock驱动. 而专门测试clock的例程是testsuites/samples下的ticker.clock是通过中断来实现的,所以接下来要添加中断.            首先,弄清楚RTEMS内核,中断的实现机制.rtems-4.6.99.3关于中断的函数调用流程如下:    rtems_exception_init_mngt安装六类异常向量地址到rtems_vector_table(在linkcmds中定义,实际地址为0x30000020)开始的地方,rtems_irq_mngt_init以实际的irq句柄初始化异常向量表,并以default_int_handler地址初始化32个rtems bsp       irq中断向量地址.当发生irq中断时,系统跳到0x00000018地址执行,0x00000018地址处装载的就是rtems_irq_mngt_init安装的实际的irq句柄,通过这个句柄就可以找到相应的32个rtems bsp irq中断向量的哪个发生了中断,从而跳到对应isr服务程序执行.            系统是怎么找到clock中断isr服务地址的,rtems-4.6.99.3关于clock中断的函数调用流程如下       到现在虽然中断句柄已经安装好了,但还没有做映射,系统怎么访问0x00000018地址呢? 11.1   MMU          记得,在start.S中我屏蔽了          ldr     r0, =mem_map/*装载映射表*/          bl      mmu_init   /*初始化mmu*/          现在要打开          程序的调试工作有回到了汇编阶段,所以,我又用LED跟踪.          一直跟踪到函数mmu_init中的 mmu_set_ctrl函数         前都没事,但调用这个函数时程序跑飞了.         我开始怀疑是C内嵌汇编出了问题,所以我把mmu_set_ctrl换成了纯汇编程序放到了start.S中,同样跟踪到了我转换后的汇编函数中。但,就在执行使能mmu这条语句时飞掉了.把这条语句屏蔽了就没事.说明不是内嵌汇编的问题.那么在执行这条语句时,cpu到底做了些什么呢?要擦看汇编及pc指针最好的办法莫过于用ads了,用AXD调试程序运行到使能mmu这条语句时也跑飞了.做了改动的地方只有       mem_map,gp32中的映射表为   我改动后为   我开始以为映射属性的问题,但怎么换都不行,后来,发现问题出在映射size上,64M的sdram只映射了9M,暂且不说,因为我程序加各堆栈再怎么样也不会超过9M,没有映射完64M也不会出什么问题.但是,Internals Regs如果没有映射完就有问题了,我对照s3c2410.h,发现,从48000000-4a000000,50000000-5a0000000而我只映射了16M也就是只映射了48000000-49000000,50000000-510000000,这么多register没有映射,当要访问没有映射的register时肯定会因找不到地址而跑飞.所以,映射所有的bank0-bank7     mmu_sect_map_t mem_map[] = { /*    */     {0x30000000, 0x00000000,   1, MMU_CACHE_NONE},     /* SDRAM for vectors */     {0x30000000, 0x30000000,   32, MMU_CACHE_WTHROUGH}, /* SDRAM W cache */     {0x32000000, 0x32000000,   32, MMU_CACHE_NONE},     /* SDRAM W/O cache */     {0x48000000, 0x48000000,   256, MMU_CACHE_NONE},    /* Internals Regs - */     {0x50000000,  0x50000000,   256, MMU_CACHE_NONE},    /* Internal Regs - */     {0x00000000, 0x00000000,   0,    0}                /* The end */ }; 这样,运行ticker例程时,看到了正确结果. 11.2 照葫芦画瓢      由于rtems-4.6.99.3源码自带的gp32-bsp中并没有网络驱动,所幸的是edp7312中有cs8900的驱动,因此可以copy edp7312目录下的整个network目录到c/src/lib/libbsp/arm/gp32下,并修改相关makefike文件,这里我把要注意的地方列出来:      ①在configure rtems-4.6.99.3时去掉disable-networking disable-posix; ②对bank3 bus设置:   /*==========Bank 3 parameter==========*/ #define B3_Tacs        0x0  /*0clk*/ #define B3_Tcos        0x3  /*0clk*/ #define B3_Tacc        0x7  /*14clk*/ #define B3_Tcoh        0x1  /*0clk*/ #define B3_Tah         0x0  /*0clk*/ #define B3_Tacp        0x3  #define B3_PMC         0x0  /*normal*/ rBANKCON3= ((B3_Tacs13)+(B3_Tcos11)+(B3_Tacc8)+(B3_Tcoh6)+(B3_Tah4)+(B3_Tacp2)+(B3_PMC)); 不然,连cs8900 ID号都读不出来. 要成功编译需要花点时间。但这不是难点!只要细心,应该没有问题。 转载:请注明,作者,下家山   请尊重原创!