《飞思卡尔16位单片机9S12XS128使用和程序》由会员分享,可在线阅读,更多相关《飞思卡尔16位单片机9S12XS128使用和程序(8页珍藏版)》请在金锄头文库上搜索。
1、飞思卡尔16位单片机9S12XS128使用 收藏 最近做一个关于飞思卡尔16位单片机9S12XS128MAA的项目,以前未做过单片机,故做此项目颇有些感触。现记录下这个艰辛历程。 以前一直是做软件方面的工作,很少接触硬件,感觉搞硬件的人很高深,现在接触了点硬件发现,与其说使用java,C#等语言写程序是搭积木,不如说搞硬件芯片搭接的更像是在搭积木(因为芯片是实实在在拿在手里的东西,而代码不是滴。还有搞芯片内部电路的不在此列,这个我暂时还不熟悉)。目前我们在做的这个模块,就是使用现有的很多芯片,然后根据其引脚定义,搭接出我们需要的功能PCB板,然后为其写程序。 废话不多说,进入正题。单片机简介:
2、 9S12XS128MAA单片机是16位的单片机80个引脚,CPU是CPU12X,内部RAM 8KB,EEPROM:2KB,FLASH:128KB,外部晶振16M,通过内部PLL可得40M总线时钟。 9S12XS128MAA单片机拥有:CAN:1个,SCI:2个,SPI:1个,TIM:8个,PIT:4个,A/D:8个,PWM:8个 下面介绍下我们项目用到的几个模块给出初始化代码1、时钟模块初始化 单片机利用外部16M晶振,通过锁相环电路产生40M的总线时钟(9S12XS128系列标准为40M),初始化代码如下: view plaincopy to clipboardprint?/*系统时钟初始
3、化*/ void Init_System_Clock() asm / 这里采用汇编代码来产生40M的总线 LDAB #3 STAB REFDV LDAB #4 STAB SYNR BRCLR CRGFLG,#$08,*/本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率 BSET CLKSEL,#$80 /*系统时钟初始化*/void Init_System_Clock() asm / 这里采用汇编代码来产生40M的总线 LDAB #3STAB REFDV LDAB #4STAB SYNRBRCLR CRGFLG,#$08,*/本句话含义为等待频率稳定然后执行下一条汇编语句
4、,选择此频率作为总线频率BSET CLKSEL,#$80 上面的代码是汇编写的,这个因为汇编代码量比较少,所以用它写了,具体含义注释已经给出,主函数中调用此函数即可完成时钟初始化,总线时钟为40M. 2、SCI模块初始化 单片机电路做好了当然少不了和PC之间的通信,通信通过单片机串口SCI链接到PC端的COM口上去。下面进行SCI初始化 view plaincopy to clipboardprint?/*初始化系统SCI*/ void Init_System_SCI() SCI0BD=260; /设置为9600bps SCIbaud_rate=PLLclock/(16*SCI0BD)SCI0
5、CR1=0; /8位模式,无奇偶校验位 SCI0CR2=0x2C; /发送允许,接受中断允许 /*初始化系统SCI*/void Init_System_SCI() SCI0BD=260; /设置为9600bps SCIbaud_rate=PLLclock/(16*SCI0BD)SCI0CR1=0; /8位模式,无奇偶校验位 SCI0CR2=0x2C; /发送允许,接受中断允许 初始化之后就可以利用SCI与PC之间的通信了,下面介绍如何与PC间通信 首先用线将单片机与PC上的COM口链接起来,具体链接使用的线需要根据RS-232串口的线的定义链接 然后PC端打开超级终端,使用9600bps,无奇
6、偶校验,然后链接即可,注意COM口选择要正确。 单片机端的发送代码如下: view plaincopy to clipboardprint?void sci_write(unsigned char sendchar) /SCI写函数 while(!(SCI0SR1&0x80);/判断发送是否准备好 SCI0DRH=0; SCI0DRL=sendchar; void sci_write(unsigned char sendchar) /SCI写函数while(!(SCI0SR1&0x80);/判断发送是否准备好SCI0DRH=0;SCI0DRL=sendchar; 单片机端的接收代码如下: vi
7、ew plaincopy to clipboardprint?unsigned char sci_read() /SCI读函数 while(SCI0SR1_RDRF!=1); return SCI0DRL; unsigned char sci_read() /SCI读函数while(SCI0SR1_RDRF!=1);return SCI0DRL; 注意了,上面的两个函数操作的都是一个字节,而不是字符串,它只能读一个字节,或者写一个字节 下面写一个简单的println函数 view plaincopy to clipboardprint?void println(unsigned char *s
8、tr) /输出字符串函数 while(*str)sci_write(*str);str+;/将str里内容发出去 sci_write(rn);/加个控制字符,便于PC端程序识别和处理 void println(unsigned char *str) /输出字符串函数while(*str)sci_write(*str);str+;/将str里内容发出去sci_write(rn);/加个控制字符,便于PC端程序识别和处理 SCI初始化时候调用println函数将向PC端发送字符串3、PWM模块初始化 PWM是脉冲调制,就是产生一定频率的方波,但是一个周期内的方波占空比是可调的,在我们的这个项目里P
9、WM是用来控制舵机和电机的,下面介绍了PWM0,PWM1为两个独立的8为PWM用于控制电机,PWM2,PWM3级联为一个16位的PWM用于控制舵机转向。 PWM模块的初始化: view plaincopy to clipboardprint?/*初始化系统PWM*/ void Init_System_PWM() /所有PWM不可用 PWME=0x00; /PWM23连级使用 PWMCTL_CON23=1; /CLOCK A,CLOCK B,预分频,CLOCKA=40/1=40M,CLOCKB=40/1=40M PWMPRCLK=0x00; /对PWM0,PWM1,PWM23计数器清零 PWMC
10、NT0=PWMCNT1 = 0; PWMCNT23=0; /SA=40M/(2*10)=2MHZ PWMSCLA=10; /SB=40M/(2*20)=1M; PWMSCLB=20; /选择SA为PWM0的频率 PWMCLK_PCLK0=1; / 选择SA为PWM1的频率 PWMCLK_PCLK1=1; /选择SB做时钟做PWM23频率 PWMCLK_PCLK3=1; /极性设置,先输出高电平,计数到DTY时,反转电平 PWMPOL_PPOL0=PWMPOL_PPOL1=1; PWMPOL_PPOL3=1; /左对齐 PWMCAE_CAE0=PWMCAE_CAE1=PWMCAE_CAE3=0;
11、 /设置PWM23的频率为1M/20K=50HZ PWMPER23=20000; PWMDTY23=10000;/占空比为50% /PWMPER0=PWMPER1=2M/100=20KHZ PWMPER1=100; PWMDTY1=50; PWMPER0=100; PWMDTY0=50; PWME_PWME3=PWME_PWME0=PWME_PWME1=1;/使能PWM3 /*初始化系统PWM*/void Init_System_PWM() /所有PWM不可用 PWME=0x00; /PWM23连级使用 PWMCTL_CON23=1; /CLOCK A,CLOCK B,预分频,CLOCKA=4
12、0/1=40M,CLOCKB=40/1=40M PWMPRCLK=0x00; /对PWM0,PWM1,PWM23计数器清零 PWMCNT0=PWMCNT1 = 0; PWMCNT23=0; /SA=40M/(2*10)=2MHZ PWMSCLA=10; /SB=40M/(2*20)=1M; PWMSCLB=20; /选择SA为PWM0的频率 PWMCLK_PCLK0=1; / 选择SA为PWM1的频率 PWMCLK_PCLK1=1; /选择SB做时钟做PWM23频率 PWMCLK_PCLK3=1; /极性设置,先输出高电平,计数到DTY时,反转电平 PWMPOL_PPOL0=PWMPOL_PPOL1=1; PWMPOL_PPOL3=1; /左对齐 PWMCAE_CAE0=PWMCAE_CAE1=PWMCAE_CAE3=0