飞思卡尔单片机各种功能程序

流水灯四种效果:

#include /* common defines and macros */ #include

#include /* derivative information */ #pragma LINK_INFO DERIV ATIVE "mc9s12xdp512"

#include "main_asm.h" /* interface to the assembly module */ unsigned char temp;

//unsigned char pa @0x200;

//unsigned char pb @0x202;

unsigned char key;

static void delay(void) {

volatile unsigned long i;

for(i=0;i<100000;i++);

}

static unsigned char random;

static void Random(void) {

random = (unsigned char)rand();

}

void effect1() {

unsigned char c;

for(c=0;c<=6;c++) {

delay();

PORTB = ~(1<

}

for(c=7;c>=1;c--) {

delay();

PORTB = ~(1<

}

}

void effect2() {

unsigned char c;

for(c=0;c<=6;c++) {

delay();

PORTB = ~(3<

}

for(c=7;c>=1;c--) {

delay();

PORTB = ~(3<

}

}

void effect3() {

unsigned char c,t=0xfe;

for(c=0;c<=7;c++) {

PORTB = t;

delay();

t<<=1;

}

}

void effect4() {

unsigned char c,t=0;

for(c=0;c<=7;c++) {

PORTB=t;

delay();

t = (t<<1)+1;;

}

}

void main(void) {

unsigned char x;

DDRA=0xf0;

DDRB=0xff;

for(;;) {

x=PORTA&0x03;

switch(x) {

case 0:effect1(); break;

case 1:effect2(); break;

case 2:effect3(); break;

case 3:effect4(); break;

}

}/* wait forever */

/* please make sure that you never leave this function */ }

//行列反转法

unsigned char key_scan() //键盘扫描函数

{ unsigned char x,row=4,col=4,key=16;

PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。PUCR寄存器的解释参见书本P113

DDRA=0x0f; //行线PA0-PA3设置为输出,列线PA4-PA7设置为输入DDRA寄存器知识参见书本P113数据方向寄存器

PORTA=0xf0; //0bxxxx0000,四条行线PA0-PA3输出四个0,相当于四条行线接地

x=PORTA&0xf0; //读取四条列线的值,并保留高4位,清除低4位的值

if(x!=0xf0) //如果四条列线不全为1,则说明有按键按下

{

switch(x)

{

case 0xe0:col=1;break; //按键在第1列

case 0xd0:col=2;break; //按键在第2列

case 0xb0:col=3;break; //按键在第3列

case 0x70:col=4;break; //按键在第4列

}

//以下开始行列反转,输入变输出,输出变输入。即行线PA0-PA3设为输入,列线PA4-PA7设为输出

DDRB=0xf0; //行线PA0-PA3设为输入,列线PA4-PA7设为输出

PORTA=0x0f;//0b0000xxxx,四条列线PA4-PA7输出四个0,相当于四条列线接地

x=PORTA&0x0f //读取四条行线的值,并保留低4位,清除高4位的值

if(x!=0x0f)//如果四条行线不全为1,则说明有按键按下

{ switch(x)

{

case 0x0e:row=1;break; //按键在第1行

case 0x0d:row=2;break; //按键在第2行

case 0x0b:row=3;break; //按键在第3行

case 0x07:row=4;break; //按键在第4行

}

key=(row-1)*4+col-1; //求出键号:0-15的整数

}

}

return key; //如果没有按键按下,则函数返回的key=16;

}

main()

{ unsigned char keyno;

while(1)

{

keyno=key_scan(); //调用键盘扫描函数获取是否有按键按下,是哪个按键按下

if(keyno<16) //keyno<16有按键按下,keyno=16则表明无按键按下

switch(keyno)

{ case 0: //每一个按键按下后要实现什么功能,程序写在这。

case 1:

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

case 10:

case 11:

case 12:

case 13:

case 14:

case 15:

}

}

}

//行扫描法1

unsigned char key_scan()

{ unsigned char x,i,temp,row=4,col=4,key=16;

//PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。PUCR寄存器的解释参见书本P113

DDRA=0x0f; //行线PA0-PA3设置为输出,列线PA4-PA7设置为输入DDRA寄存器知识参见书本P113数据方向寄存器

PORTA=0xf0; //0bxxxx0000,四条行线PA0-PA3输出四个0,相当于四条行线接地

x=PORTA&0xf0; //读取四条列线的值,并保留高4位,清除低4位的值

if(x!=0xf0) //如果四条列线不全为1,则说明有按键按下

{

switch(x)

{

case 0xe0:col=1;break; //按键在第1列

case 0xd0:col=2;break; //按键在第2列

case 0xb0:col=3;break; //按键在第3列

case 0x70:col=4;break; //按键在第4列

}

//以下开始从第1行到第4行逐行判断按键是否在该行

temp=0b11111110;

for(i=1;i<=4;i++) //i代表正在判断按下的按键是否是在第i行

{

PORTA=temp; //第i行所在的行线输出0,其他三条行线输出1

x=PORTA&0xf0;//读取四条列线的值,并保留高4位,清除低4位的值

if(x!=0xf0) //如果四条列线不全为1,则说明按键就在第i行,否则表明按键不在该行,则准备扫描下一行

{ row=i;

key=(row-1)*4+col-1; //求出按键

return key; //退出key_scan函数

}

temp=(temp<<1) +1; //按键不在该行,则改变temp的值,为扫描下一行做准备。

}

}

return key; //如果没有按键按下,程序才回执行到这,此时key为初值16;

}

main()

{ unsigned char keyno;

while(1)

{

keyno=key_scan(); //调用键盘扫描函数获取是否有按键按下,是哪个按键按下

if(keyno<16) //keyno<16有按键按下,keyno=16则表明无按键按下

switch(keyno)

{ case 0: //每一个按键按下后要实现什么功能,程序写在这。

case 1:

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

case 10:

case 11:

case 12:

case 13:

case 14:

case 15:

}

}

}

PWM模块:

void PWM_Init(void)

{

PWME = 0x00; //禁止PWM模块

PWMPRCLK = 0x06; //CLOCKA的预分频设置为6,分频系数64 PWMSCLA = 125; //SA的分频因子设置为125,分频系数250

PWMCLK = 0x01; //通道0选择SA作为PWM时钟

PWMPER0 = 200; //通道0周期寄存器设置为200

PWMDTY0 = 100; //通道0占空比寄存器设置

PWMPOL = 0x01; //PWM输出先为高电平,之后变为低电平

PWMCAE = 0x00; //左对齐输出

PWMCTL = 0x00; //不级联

PWME = 0x01; //使能PWM通道0

}

void main(void){

byte LedCnt=0;

setbusclock();

PWM_Init();

for(;;)

{

}

}

void interrupt 0 _Startup(void) {

INIT_SP_FROM_STARTUP_DESC(); //初始化堆栈指针SP

main();

}

输入捕捉(求占空比):

#include /* common defines and macros */

#include "derivative.h" /* derivative-specific definitions */ #include

#include

unsigned int x,y;

unsigned long int n,Th,Tl;

unsigned char t,a;

void TIM_Init()

{

TSCR1=0x00;

TSCR2=0x84;

TIOS_IOS0=0;

TCTL4=0x01;

TIE_C0I=0x01;

TSCR1|=0x80; //启动定时器

}

#pragma CODE_SEG_NEAR_SEG NONBANKED

void interrupt 8 TIM_Tie()

{

y=x;

x=TC0;

if(TCTL4==0x02)

Th=(x-y+(n<<16))*t;

if(TCTL4==0x01)

Tl=(x-y+(n<<16))*t;

TFLG1|=0x01; //写1清零

n=0;

a=TCTL4;

a=~a&0x03;

TCTL4=a;

}

#pragma CODE_SEG_NEAR_SEG NONBANKED

void interrupt 16 TIM_Tof()

{

n++;

TFLG2|=0x80; //写1清零

}

void main(void) {

TIM_Init();

for(;;) {

// _FEED_COP(); /* feeds the dog */

} /* loop forever */

/* please make sure that you never leave main */

}

电子时钟(包含串口通信和定时器):

//知识点1: 串口初始化、串口数据收发及数据处理

// 2: 定时器如何实现指定的定时时间

#include

#include

#include "IO_Map.h"

//#include "derivative.h"

// global variables definitions

static int waittime = 5;

static unsigned char redButtonDown = FALSE, blueButtonDown = FALSE;

static long absoluteTime = 0;

unsigned int count=0;

unsigned char time[3]={0,0,0};

unsigned char cmd_buf[8];

unsigned char pos=0;

static const char segs[]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f}; //static const char //segss[]={~0xbf,~0x86,~0xdb,~0xcf,~0xe6,~0xed,~0xfd,~0x87,~0xff,~0xef}; //#pragma CODE_SEG DEFAULT

static void WriteToSCI0(const char *text){

while (*text != '\0'){

while (!(SCI0SR1 & 0x80)); // wait for output buffer empty

SCI0DRL = *text++;

}

}

void execute_cmd()

{ unsigned char tmp[3];

if ((cmd_buf[0]=='t')&&(pos==7))

{

tmp[0]=(cmd_buf[1]-'0')*10+cmd_buf[2]-'0';

tmp[1]=(cmd_buf[3]-'0')*10+cmd_buf[4]-'0';

tmp[2]=(cmd_buf[5]-'0')*10+cmd_buf[6]-'0';

if ((tmp[0]<24)&&(tmp[1]<60)&&(tmp[2]<60))

{

time[0]=tmp[0];

time[1]=tmp[1];

time[2]=tmp[2];

}

}

pos=0;

}

//*

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void interrupt 20 SCI0_ISR(void){

unsigned char rc;

rc = SCI0SR1; // dummy read to clear flags

rc = SCI0DRL; // data read

if(rc!=0x0d)

cmd_buf[pos++]=rc;

else

execute_cmd();

SCI0DRL = rc;

}

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void setbusclock(void)

{

CLKSEL=0X00; // disengage PLL to system

PLLCTL_PLLON=1; // turn on PLL

SYNR=0x00 | 0x01; // VCOFRQ[7:6];SYNDIV[5:0]

// fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) fVCO= 2*fOSC*2/2=2*fOSC

// fPLL= fVCO/(2 × POSTDIV) fPLL= fVCO;

// fBUS= fPLL/2 fBUS= fPLL/2=fosc;

// VCOCLK Frequency Ranges VCOFRQ[7:6]

// 32MHz <= fVCO <= 48MHz 00

// 48MHz < fVCO <= 80MHz 01

// Reserved 10

// 80MHz < fVCO <= 120MHz 11

REFDV=0x80 | 0x01; // REFFRQ[7:6];REFDIV[5:0]

// fREF=fOSC/(REFDIV + 1)

// REFCLK Frequency Ranges REFFRQ[7:6]

// 1MHz <= fREF <= 2MHz 00

// 2MHz < fREF <= 6MHz 01

// 6MHz < fREF <= 12MHz 10

// fREF > 12MHz 11

// pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;

POSTDIV=0x00; // 4:0, fPLL= fVCO/(2xPOSTDIV)

// If POSTDIV = $00 then fPLL is identical to fVCO (divide by one).

_asm(nop); // BUS CLOCK=16M

_asm(nop);

while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;

CLKSEL_PLLSEL =1; //engage PLL to system;

}

void interrupt 26 MDC_ISR(void) //定时器MDC模块中断服务程序,当定时时间到时自动执行该程序

{

MCFLG|=0X80;//MCFLG_MCZF=1;

count++;

if (count%10==0)

{

count=0;

time[2]++;

if(time[2]>=60)

{

time[2]=0;

time[1]++;

if(time[1]>=60)

{

time[1]=0;

time[0]++;

if(time[0]>=24)

time[0]=0;

}

}

}

}

//*/

#pragma CODE_SEG DEFAULT

static void SCI0Init(void) {

SCI0BDL = (unsigned char)((16000000UL /* OSC freq */ / 2) / 9600 /* baud rate */ / 16 /*factor*/);

SCI0CR2 = 0x2C;

}

void MDC_Init() {

unsigned char i;

MCCTL=0b11101111; //MCZI=1,MODMC=1,RDMCL=1,

ICLAT=0,FLMC=1,MCEN=0,MCPR1-0=0b11(16分频) MCCNT=10000; //定时10000us=10ms

//MCCTL_MCEN=1;

}

void main(void) {

unsigned char tmp;

DDRA = 0xFF;

DDRB = 0xFF;

DDRE = 0xFF;

DDRP = 0xFF;

DDRM = 0xFF;

DDRT = 0xFF;

PORTA =0xFF;

PORTB =0xFF;

PORTE =0xFF;

PTP =0xFF;

PTM =0xFF;

PTT =0xFF;

setbusclock();

//startTimeBase();

SCI0Init();

MDC_Init();

WriteToSCI0("\n\n*** Timer Demo ***\n"); WriteToSCI0("\nEnter 't123456' to set time to 12:34:56\n"); INTCR_IRQEN=0; //屏蔽IRQ中断EnableInterrupts; //使能全局中断

for (;;){

if(time[2]!=tmp) //if 秒钟数有更新

{

tmp=time[2];

PORTA = segs[time[0]/10];

PORTB = segs[time[0]%10]&0x7f;

PORTE = segs[time[1]/10];

PTP = segs[time[1]%10]&0x7f;

PTM = segs[time[2]/10];

PTT = segs[time[2]%10];

}

}

}

飞思卡尔程序调试技巧

一、前言 调试程序,是软件开发过程中的一个必不可少的环节。这篇帖子,匠人试着来整理一下一些调试的技巧。 说到“技巧”,这个词自从被所长批臭之后,匠人就吓得不敢再提,生怕一不小心就暴露了思想的浅薄和眼光的局限,呵呵。所以咱们不叫“技巧”,干脆低调点,就叫“雕虫小技”吧。 这里所讨论的“调试”技巧,有些是必须结合开发工具本身的功能来实现,而有些可以通过烧录芯片来验证。 各种开发工具,提供的功能多少强弱也不尽相同,这些方法也未必都能套用。仅供参考吧。 最后说明一下,这是没有草稿的帖子,匠人仍然以不定期连载的方式,边写边发边改。可能结构会比较混乱。欢迎大家一起参与讨论。 二、磨刀不误砍柴功 在调试之前,需要掌握以下一些基本功: 1、熟悉当前的开发(调试)环境,比如:设置断点、单步运行、全速运行、终止运行,查看RAM、 查看堆栈、查看IO口状态……总之,要熟练掌握基本操作的方法,并深刻了解其中意义。 2、了解芯片本身的资源和特性。 3、了解一点汇编语言的知识。(本来匠人是准备写“精通”的,但考虑到现状,还是“放低”这方面的要求 罢了)。 4、掌握基本的电路知识和排错能力。(软件调试有时也会牵涉到硬件原因。总不能连三极管的好坏都 不能识别吧?) 5、万用表、示波器、信号发生器……这些工具总该会用吧? 6、搜索、鉴别资料的能力。(内事问百度、外事问古狗、有事没事上21ic网) 7、与人沟通,描述问题的能力。(调试36计的最后一计——就是向他人讨教。当然,你得把话说明 白才行) 差不多了,如果上述7把砍柴刀磨好了,就可以开始调试了。接下来,请调入你的程序…… 三、优先调试人机界面 面对程序中的一大堆模块,无从下手是吗?好吧,匠人告诉你,先调显示模块,然后是键盘。 为什么要先调显示模块?道理很简单,我们说“眼睛是心灵的窗户”,同样,“显示是程序的窗户”。一旦把显示模块调试好了,就可以通过这个窗口,偷窥(天呐,这两个居然是敏感字!)程序内部的数据和状态了。 然后紧接着,就是调试键盘模块。有了这个按键,我们就可以人工干预程序的运行了。 ——什么,你的程序没有显示和按键? ——这位童鞋,你真不幸,请去检查一下自己的人品和星座运程先。谢谢。 实在是没显示?再看看系统有蜂鸣器吗?如果侥幸有的话,也能凑合着发发提示声音吧? 或者,有串口吗?可以考虑借助PC 端的串口调试软件来收发数据,这也是一个间接的人机交流方法。 总而言之,要尽快建立人机交流界面。 四、慢镜头的威力 2009年春晚捧红了魔术师刘谦(这位老兄名“谦”,其实一点都不谦虚——长的帅不是错,出来拽就是罪过了!),也勾起了大家对魔术的浓厚兴趣,如何识破那些快速的眼花缭乱的魔术手法呢?很简单,用慢镜头回放即可。据说刘谦那个橡皮筋魔术的手法就是被人如此识破的。 回到我们单片机上来。我们知道,单片机的运行速度,一般都是在几M到几十M(当然,也有为了节能而采用几十K的低速)。不管怎么样,这个速度都远远超出了我们人眼能够分辨的速度。眼睛一眨,也许几M条指令已经执行过去了。 比如说数码管显示(假设有4位数码管)。平时我们看到数码管同时点亮着,但是实际上,这4个数码管是逐个扫描的。在任意一个时刻,只有一位数码管被点亮。在微观上,我们可以进一步把每位数码

飞思卡尔16位单片机9S12XS128使用和程序

飞思卡尔16位单片机9S12XS128使用收藏 最近做一个关于飞思卡尔16位单片机9S12XS128MAA的项目,以前未做过单片机,故做此项目颇有些感触。现记录下这个艰辛历程。 以前一直是做软件方面的工作,很少接触硬件,感觉搞硬件的人很高深,现在接触了点硬件发现,与其说使用java,C#等语言写程序是搭积木,不如说搞硬件芯片搭接的更像是在搭积木(因为芯片是实实在在拿在手里的东西,而代码不是滴。还有搞芯片内部电路的不在此列,这个我暂时还不熟悉)。目前我们在做的这个模块,就是使用现有的很多芯片,然后根据其引脚定义,搭接出我们需要的功能PCB板,然后为其写程序。 废话不多说,进入正题。 单片机简介: 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? /******************系统时钟初始化****************/ void Init_System_Clock() { asm { // 这里采用汇编代码来产生40M的总线 LDAB #3 STAB REFDV LDAB #4 STAB SYNR BRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率 BSET CLKSEL,#$80 } }

C语言实现控制电机加减速正反转(飞思卡尔C代码)

用单片机控制直流电动机的正反转、加减速的程序如何用C语言写 参考一下这个例子吧。 #include #define uchar unsigned char #define uint unsigned int sbit PW1=P2^0 ; sbit PW2=P2^1 ; //控制电机的两个输入 sbit accelerate=P2^2 ; //调速按键 sbit stop=P2^3 ; //停止按键 sbit left=P2^4 ; //左转按键 sbit right=P2^5 ; //右转按键 #define right_turn PW1=0;PW2=1 //顺时针转动 #define left_turn PW1=1;PW2=0 //逆向转动 #define end_turn PW1=1;PW2=1 //停转 uint t0=25000,t1=25000; //初始时占空比为50% uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值 uchardflag; //左右转标志 uchar count; //用来标志速度档位 void keyscan(); //键盘扫描 void delay(uchar z); void time_init(); //定时器的初始化 void adjust_speed(); //通过调整占空比来调整速度 //**********************************// void main() { time_init(); //定时器的初始化 while(1) { keyscan(); //不断扫描键盘程序,以便及时作出相应的响应 } }

飞思卡尔单片机中断

飞思卡尔单片机中断 一、引言 飞思卡尔单片机,作为嵌入式系统中的重要一环,广泛应用于各种实时控制系统中。其中,中断处理是单片机实现实时响应的关键所在。本文将详细介绍飞思卡尔单片机的中断原理与应用。 二、飞思卡尔单片机中断概述 飞思卡尔单片机具有完善的中断系统,能够满足各种实时控制需求。中断系统主要包括中断源、中断优先级、中断处理程序等部分。其中,中断源包括外部硬件中断、内部定时器中断、串口通信中断等;中断优先级则根据中断源的重要性和紧急程度进行设定。 三、飞思卡尔单片机中断处理流程 飞思卡尔单片机的中断处理流程主要包括以下几个步骤: 1、中断申请:中断源向CPU发出中断请求,CPU收到请求后进行判断,如果满足中断条件,则进行下一步处理。 2、中断识别:CPU根据中断标志位和优先级,识别出对应的中断源,然后进行下一步处理。

3、保存现场:CPU将当前运行的程序现场保存下来,以便后续恢复执行。 4、执行中断服务程序:CPU跳转到对应的中断服务程序,执行其中的指令代码。 5、恢复现场:执行完中断服务程序后,CPU恢复之前保存的现场,然后继续执行之前的程序。 四、飞思卡尔单片机中断应用实例 以一个简单的外部硬件中断为例,说明飞思卡尔单片机中断的具体应用。该中断源是一个按钮,当按下按钮时,会产生一个外部硬件中断请求。CPU收到请求后,会执行相应的中断服务程序,实现LED灯的亮灭控制。通过这种方式,可以实现单片机的实时响应和控制。五、总结 飞思卡尔单片机的中断系统是其重要的组成部分,对于实现实时控制具有重要意义。通过了解飞思卡尔单片机中断的原理和应用,可以更好地发挥其优势,实现更为精准和实时的控制系统设计。在未来的嵌入式系统设计中,飞思卡尔单片机的中断系统将会发挥越来越重要的作用。

FreeScale_HCS12系列单片机教程(dg128)

HCS12微控制器系列教程---第一讲:PWM 模块介绍 该教程以MC9S12DG128单片机为核心进行讲解,全面阐释该16位单片机资源。本文为第一讲,开始介绍S12 MCU的PWM模块。 PWM 调制波有8 个输出通道,每一个输出通道都可以独立的进行输出。每一个输出通道都有一 ,一个周期控制寄存器和两个可供选择的时钟源。每一个PWM 输出个精确的计数器(计算脉冲的个数) 通道都能调制出占空比从0—100% 变化的波形。 PWM 的主要特点有: 1、它有8 个独立的输出通道,并且通过编程可控制其输出波形的周期。 2、每一个输出通道都有一个精确的计数器。 3、每一个通道的PWM 输出使能都可以由编程来控制。 4、PWM输出波形的翻转控制可以通过编程来实现。 5、周期和脉宽可以被双缓冲。当通道关闭或PWM计数器为0时,改变周期和脉宽才起作用。 6、8 字节或16 字节的通道协议。 ,他们提供了一个宽范围的时钟频率。 7、有4 个时钟源可供选择(A、SA、B、SB) 8、通过编程可以实现希望的时钟周期。 9、具有遇到紧急情况关闭程序的功能。 10、每一个通道都可以通过编程实现左对齐输出还是居中对齐输出。 HCS12微控制器系列教程---第二讲:PWM 寄存器简介 1、PWM启动寄存器PWME PWME 寄存器每一位如图1所示: 复位默认值:0000 0000B 图1 PWME 寄存器 每一个PWM 的输出通道都有一个使能位PWMEx 。它相当于一个开关,用来启动和关闭 相应通道的PWM 波形输出。当任意的PWMEx 位置1,则相关的PWM输出通道就立刻可用。 用法:PWME7=1 --- 通道7 可对外输出波形 PWME7=0 --- 通道7 不能对外输出波形 注意:在通道使能后所输出的第一个波形可能是不规则的。当输出通道工作在串联模式时(PWMCTL寄存器中的CONxx置1),那么)使能相应的16位PWM 输出通道是由PWMEx的高 位控制的,例如:设置PWMCTL_CON01 = 1,通道0、1级联,形成一个16位PWM 通道,由通道1 的使能位控 制PWM 的输出。 2、PWM时钟选择寄存器PWMCLK PWMCLK寄存器每一位如图3所示: 复位默认值:0000 0000B 图2 PWMCLK 寄存器 S12的PWM 共有四个时钟源,每一个PWM 输出通道都有两个时钟可供选择(Clock A、Clock SA 或Clock B、Clock SB))。其中0、1、4、5通道可选用Clock A和ClockSA,2、3、6、7通道可选用ClockB、ClockSB通道。该寄存器用来实现几个通道时钟源的选择。 用法:PCLK0 =1 --- 通道0(PTP0)的时钟源设为ClockSA

飞思卡尔入门程序总结

1.对IO口输入输出操作程序举例:A口接流水灯并实现闪烁 void main(void) { while(1) { DDRA=0xff; delay(500); PORTA=0xff; delay(500); PORTA=0; } 另外,B、E口的IO功能操作也是一样的,因为位数一样寄存器一样,其他口的寄存器就不太一样了!J,P,M,T,S这五个口除具有数据寄存器外,他们都另外多出另一个端口输入寄存器(该寄存器功能我未知)! 2.SPI总线接口 SPI是一种高速高效的同步串行接口,这种接口主要用于MCU与外部的接口芯片交换数据,只要有SPI口的芯片都可以与单片机相连形成主从机系统进行数据的传递,比如SPI用于移位寄存器74HC164,这是个串入并出的芯片这样可以实现扩展IO口。 还有AD转换芯片AD7793,可以实现数模转换,还有飞思卡尔公司的电源管理芯片MC33389。 因设备有限此功能待以后调试! 3.SCI总线接口 MC9S12DG128单片机有两个SCI模块,可以选用其中任何一个。他的使用有8个相应寄存器共设置,其中有波特率设置寄存器SCIBDH,SCIBDL,还有控制寄存器SCICR1,SCICR2,状态寄存器SCISR1,SCISR2,数据寄存器SCIDRH,SCIDRL; 简单讲SCI的使用就是寄存器初始化,数据传送方式设置,下面举个初始化使用的简单例子:SCICR2=0x08;//发送使能设置 SCIBDH=0x00;//波特率设置为9600 SCIBDL=0x9c; 就是这样这个是简单实用时的设置,发送函数如下: While(!(SCISR1&0x40))//检测是否发送完毕,一旦发送完毕就进入到死循 环里边 {} SCIDRL=C;//C代表需要传送的数据 4.有关定时器TCNT TCNT是芯片内部的16位主定时器,他不停地对内部时钟信号进行计数,从0x0000直到0xffff,计满后溢出又返回到0x0000,程序随时可以读取,但在普通模式下禁止写入。 TCNT应该按字访问,分别访问高低字节将出现错误! 可以直接利用它的来实现一些延时的功能! 例如下面的程序: #include #include "derivative.h" void TimerOverflow() { unsigned char i=1,j=0x80;

飞思卡尔QG8实验教程

第一章基础理论 1.1 单片机程序设计与应用系统开发过程 单片机的行为是受程序控制的,因此开发与使用单片机必然会遇到程序设计的问题,单片机设计是一个硬件与软件结合的问题,而其软件设计的工作往往占有更多的成分。一个完整的嵌入式系统开发过程,除了硬件电路的设计外,软件工作包括程序编辑、汇编或编译、程序下载、程序调试、脱机验证等过程。 程序的编辑就是按照一定的格式,采用汇编或者C等高级语言进行编写。早期的单片机程序设计在DOS环境下符合一定的格式编辑,然后采用一个合适的软件汇编,生成二进制等CPU能识别的目标代码,将单片机(内带程序存储器的情形)或程序存储器放入编程器,编程器通过串口或USB等接口与PC机相连,将PC机存放的CPU能识别的代码下载到单片机或程序存储器中。图1-1是一个简单的说明。 图1-1 程序设计过程 采用以上方式进行开发的情形下,单片机必须是能从电路板上取下来,这对贴片封装的单片机就无能为力了。此时为了能在线仿真调试,需要昂贵的仿真头和仿真电缆与软件,而且几乎没有仿真器能做到100%的功能仿真,甚至有的问题正是来自于仿真器。随着技术的发展,采用ISP技术,只要在目标电路板上预留一个接口,通过一个很小的下载器,与PC 机串、并口或USB口相连,就可以进行程序的调试与下载,尤其是有的单片机具有JTAG接口,下载调试更加方便,调试尽可能少占用单片机资源,更有甚者,像freescale的单片机,内置背景调试控制器(BDC ,Background Debug Controller),支持一线ISP和程序调试。目前程序开发需要的各种软件,如编辑、汇编、编译、链接、调试、下载等都集成到一个环境下(集成开发环境IDE),这些开发环境有的是针对某种单片机,由单片机厂商提供,有的则比较通用一些,这些开发环境如Silicon Laboratories,AVR Studio,Keil uVision,Freescale CodeWarrior等。 对于单片机初学者而言,进行单片机入门级的学习,建议手头具备如下材料: (1)某款单片机的完整的数据手册。需要搞清楚存储器配置情况,程序应该放在哪,数据与变量应该放在哪,程序是如何放入单片机中的(如果单片机中有程序存储器的话),如果单片机支持ISP功能,最好动手做一个下载器; (2)拥有使用单片机的完整的指令系统,寻址方式如果不太好掌握,先看指令。建议采用C等高级语言编程,这样可以避免学习枯燥难记的汇编指令。最好有一些例程,以及若干能完成某种功能的程序模块,包括对单片机管脚的电平控制程序。必须掌握程序的总体结构、变量的定义、程序开始位置、中断入口与处理方法、单片机I/O口的控制,单片机寄存器的控制等; (3)选择并确定合适的程序设计开发环境与编译器,了解程序设计中辅助汇编与编译的伪指令,通过实例了解程序设计中应该包含的头文件和库文件;了解集成开发环境中的程序调试与模拟仿真方法;

(整理)飞思卡尔8位单片机MC9S08JM60开发板实践教程

第一章搭建实验环境 系统时钟设置 #include "App\Include\App.h" #ifndef _MCG_C #define _MCG_C //oscillator 12MHZ 倍频为24MHZ()先8分频后16倍频 void S_MCGInit(void) { /* the MCG is default set to FEI mode, it should be change to FBE mode*/ /************************************************************************** *********** MCGC2 [7:6] BDIV 总线频率分频因子–选择由MCGC1寄存器中CLKS位决定的时钟源的分频。这控制总线频率。 00 编码0 –时钟1分频 01 编码1 –时钟2分频(复位后默认) 10 编码2 –时钟4分频 11 编码3 –时钟8分频 [5] RANGE 频率范围选择–选择外部振荡器或者外部时钟源的频率范围。 1 选择1MHz到16MHz外部振荡器的频率范围。(1MHz到40MHz的外部时钟电源)的高频率范围 0 选择32kHz到100kHz外部振荡器的频率范围。(32kHz到1MHz的外部时钟电源)的低频率范围 [4] HGO 高增益振荡器选择–控制外部振荡器操作模式。 1 配置外部振荡器为高增益运行 0 配置外部振荡器为低功耗运行 [3] LP 低功耗选择–控制在忽略模式中FLL(或者PLL)是否为无效 1 FLL(或PLL)在忽略模式(低功耗)中为无效的。 0 FLL(或PLL)在忽略模式中为无效的。

飞思卡尔单片机各种功能程序

流水灯四种效果: #include /* common defines and macros */ #include #include /* derivative information */ #pragma LINK_INFO DERIV ATIVE "mc9s12xdp512" #include "main_asm.h" /* interface to the assembly module */ unsigned char temp; //unsigned char pa @0x200; //unsigned char pb @0x202; unsigned char key; static void delay(void) { volatile unsigned long i; for(i=0;i<100000;i++); } static unsigned char random; static void Random(void) { random = (unsigned char)rand(); } void effect1() { unsigned char c; for(c=0;c<=6;c++) { delay(); PORTB = ~(1<=1;c--) { delay(); PORTB = ~(1<=1;c--) {

飞思卡尔智能车程序

#include /* common defines and macros */ #include /* derivative-specific definitions */ #pragma LINK_INFO DERIV ATIVE "MC9S12XS128.h" ///////////////////////////////////////////////////// word AD_Value[16];//AD转换结 int Done_cache[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//记忆 int Angle_cache[20]={50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50};//记忆////////////////////////////////////////////////////// #define PAEN 6 ///////////////////////////////////////////////////// unsigned int i=0,Xmax=0,Ymax=0,Xmax2=0,Ymax2=0; unsigned int flag=0; unsigned int Snake_flag=0; unsigned int SenA=50; unsigned int Out_flag=0; unsigned int DuoJi_angle; unsigned int Turn_flag=0; unsigned int Keep_flag=0; unsigned int Run_Time_Count=0; /////////////////////////////////////////////////////////////////// unsigned int Speed=0, Count=0;//count=2即4秒测一次速度 unsigned int ii=0,tt=0; int Goal_speed=15; int E1=0; int E2=0; int DE=0; int B1=0; int B2=0; int OUT=0; ////////////////////////////////////////////////////// #include "Initiate.h" #include "Basic.h" #include "5110.h" #include "Control.h" ////////////////////////////////////////////////////////////////////// void main(void) { SetBusCLK_64M();

舵机工作原理详解及智能车单片机(飞思卡尔)控制的实现(程序)

舵机工作原理详解及单片机(飞思卡尔和51)控制的实现(程序) 1、概述 舵机最早出现在航模运动中。在航空模型中,飞行机的飞行姿态是通过调节发动机和各个控制舵面来实现的。举个简单的四通飞机来说,飞机上有以下几个地方需要控制: 1.发动机进气量,来控制发动机的拉力(或推力); 2.副翼舵面(安装在飞机机翼后缘),用来控制飞机的横滚运动; 3.水平尾舵面,用来控制飞机的俯仰角; 4.垂直尾舵面,用来控制飞机的偏航角; 遥控器有四个通道,分别对应四个舵机,而舵机又通过连杆等传动元件带动舵面的转动,从而改变飞机的运动状态。舵机因此得名:控制舵面的伺服电机。 不仅在航模飞机中,在其他的模型运动中都可以看到它的应用:船模上用来控制尾舵,车模中用来转向等等。由此可见,凡是需要操作性动作时都可以用舵机来实现。 2、结构和控制 一般来讲,舵机主要由以下几个部分组成,舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。 工作原理:控制电路板接受来自信号线的控制信号(具体信号待会再讲),控制电机转 动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机的转动方向和速度,从而达到目标停止。舵机的基本结构是这样,但实现起来有很多种。例如电机就有有刷和无刷之分,齿轮有塑料和金属之分,输出轴有滑动和滚动之分,壳体有塑料和铝合金之分,速度有快速和慢速之分,体积有大中小三种之分等等,组合不同,价格也千差万别。例如,其中小舵机一般称作微舵,同种材料的条件下是中型的一倍多,金属齿轮是塑料齿轮的一倍多。需要根据需要选用不同类型。

飞思卡尔9S12XS128 单片机教程

9S12XS128 单片机开发工具包 清华Freescale MCU/DSP 应用开发研究中心 9S12XS128单片机开发工具包 (1) 概述 (3) 9S12XS128单片机 (3) 9S12XS128开发工具包组件 (3) 9S12XS128开发板及与PC 通信 (4) 9S12XS128 开发板 (4) 开发板的硬件连接 (5) PC机的设置 (6) 监控程序及监控命令详解 (8) 命令详解 (8) 复位、中断向量表 (12) 用户可以使用的RAM空间 (12) 编译器CodeWarrior for HCS12 使用方法入门 (13) 建立工程文件 (13) 编写main.c 程序 (15) 定义存储空间分配 (17) 应用程序的编译 (18) 向开发板下载程序 (20) 运行应用程序 (21)

概述 这里描述的是一套9S12XS128 系列单片机开发系统套件。以后的更新的版本见清华Freescale单片机应用开发研究中心的网站:https://www.360docs.net/doc/9219177498.html,。 开发系统主要由两个部分组成,分别是调试下载用的TBDML和开发用目标板。其中TBDML的使用请参见文档“BDM for S12(TTBDM)用户手册V 34.pdf”。 目标板是有异步串行口的驱动的基本系统。针对9S12XS128 芯片我们编写了 9S12XS128目标板监控程序,可以方便地完成应用系统的开发。用户可以在此基础上设计自己所需的目标母板,完成项目的初期开发。应用软件完成后,用开发工具板擦除监控程序,下载最终的应用程序。 9S12XS128 单片机 S12XS 16 位微控制器系列针对一系列成本敏感型汽车车身电子应用进行了优化。 S12X 产品满足了用户对设计灵活性和平台兼容性的需求,并在一系列汽车电子平台上实 现了可升级性、硬件和软件可重用性、以及兼容性。 S12XS 系列可以经济而又兼容地扩展至带XGate 协处理器的S12XE 系列单片机,从 而为用户削减了成本,并缩小了封装尺寸。S12XS系列帮助设计者迅速抓住市场机遇,同时还能降低移植成本。 主要特性: S12X CPU,最高总线速度40MHz 64KB、128KB 和256KB 闪存选项,均带有错误校正功能(ECC) 带有ECC 的、4KB 至8KB DataFlash,用于实现数据或程序存储 可配置8- 、10- 或12- 位模数转换器(ADC),转换时间3μs 支持控制区域网(CAN)、本地互联网(LIN)和串行外设接口(SPI)协议模块 带有16-位计数器的、8-通道定时器 出色的EMC,及运行和停止省电模式 9S12XS128 开发工具包组件 9S12XS128开发工具包硬件系统包括以下组件: (1) 驻留监控程序的9S12XS128开发板一块; (2) 带USB 接口的TBDML调试器一个,简称BDM头; (3) BDM 6芯扁带电缆一根; (4)USB电缆一根; (5) RS-232 串口通信线一根; (6) 220V AC~DC +5V电源一个; (7) CD 光盘一张,含CodeWarrior V4.7,可下载的S12X监控程序.S19。 9S12XS128开发板及与PC通信 9S12XS128 开发板 9S12XS128开发板如图1 所示: 图1 PC9S12XS128 开发板 板上有构成最小系统必要的复位电路、晶体振荡器及时钟电路,串行接口的RS-232 驱 动电路,+5V电源插座。单片机中已经写入了开发的监控程序。单片机的大部分I/O端口都通过两个64芯的欧式插头引出。这两个插头在PCB上的距离为190mil,如图2所示。表1、表2给出了开发板上P1与P2 插座的引脚定义。用户可以根据图2和表1的定义设计自己的应用系统,即目标母板,然后将开发板插在目标母板上调试。

飞思卡尔MC9S12单片机试验程序

定时器模块 1:输出比较 定时器延时,中断点亮led 灯 #include /* common defines and macros */ #include //void interrupt 8 aabreak(void); unsigned int flag=0; /* derivative information */ // 此行可以注释掉******* void main(void) { EnableInterrupts; TFLG1=0x01; DDRB=0xff; PORTB=0xff; // 清中断标志位 // 将 B 口定义为输出,首先输出全0 TSCR1=0x80; TSCR2=0x01; TIE=0x01; TIOS=0x01; TCTL2=0x00; TFLG1=0x01; TC0=0x00f0; for(;;); // 定时器使能,正常工作 // 将定时器进行128 分频最高位不要开******** // 定时器0 的中断使能 // 将定时器设置为输出比较状态 // 定时器与引脚断开 // 清中断标志位 // 给定时器赋值 } #pragma CODE_SEG NON_BANKED void interrupt 8 aabreak(void)// 中断号要正确,是中断8 (从0 通道开始算起的) { TFLG1=0x01; if(flag==0) { PORTB=0xaa; flag=1; // 清中断标志位 } else{ PORTB=0x55; flag=0; } TC0=0x00f0; // 给定时器赋值 }

【精品】飞思卡尔单片机编程

关于Codewarrior 中的。prm 文件 网上广泛流传的一篇文章讲述的是8位飞思卡尔单片机的内存映射,这几天,研究了一下Codewarrior5.0prm文件,基于16位单片机MC9S12XS128,一点心得,和大家分享。有什么错误请指正。 正文: 关于Codewarrior中的.prm文件 要讨论单片机的地址映射,就必须要接触.prm文件,本篇的讨论基于Codewarrior5。0编译器,单片机采用MC9S12XS128。 通过项目模板建立的新项目中都有一个名字为“project。prm”的文件,位于ProjectSettings-〉LinkerFiles文件夹下。一个标准的基于XS128的.prm文件起始内容如下: .prm文件范例: NAMES END

SEGMENTS RAM =READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF; ROM_4000 =READ_ONLY DATA_NEAR IBCC_NEAR 0 x4000 TO 0x7FFF; ROM_C000 =READ_ONLY DATA_NEAR IBCC_NEAR 0 xC000 TO 0xFEFF; //OSVECTORS =READ_ONLY 0xFF10 TO 0xFFFF; EEPROM_00 =READ_ONLY DATA_FAR IBCC_FAR 0x 000800 TO 0x000BFF; EEPROM_01 =READ_ONLY DATA_FAR IBCC_FAR 0x 010800 TO 0x010BFF; EEPROM_02 =READ_ONLY DATA_FAR IBCC_FAR 0x 020800 TO 0x020BFF;

飞思卡尔MC9S12XS128单片机各模块使用方法及寄存器配置

飞思卡尔MC9S12XS128单片机各模块使用方法 及寄存器配置 手把手教你写S12XS128程序--PWM模块介绍 该教程以MC9S12XS128单片机为核心进行讲解,全面阐释该16位单片机资源。本文为第一讲,开始介绍该MCU的PWM模块。 PWM 调制波有8个输出通道,每一个输出通道都可以独立的进行输出。每一个输出通道都有一个精确的计数器(计算脉冲的个数),一个周期控制寄存器和两个可供选择的时钟源。每一个P WM 输出通道都能调制出占空比从0—100% 变化的波形。 PWM 的主要特点有: 1、它有8个独立的输出通道,并且通过编程可控制其输出波形的周期。 2、每一个输出通道都有一个精确的计数器。 3、每一个通道的P WM 输出使能都可以由编程来控制。 4、PWM 输出波形的翻转控制可以通过编程来实现。 5、周期和脉宽可以被双缓冲。当通道关闭或PWM 计数器为0时,改变周期和脉宽才起作用。 6、8 字节或16 字节的通道协议。 7、有4个时钟源可供选择(A、SA、B、SB),他们提供了一个宽范围的时钟频率。 8、通过编程可以实现希望的时钟周期。 9、具有遇到紧急情况关闭程序的功能。 10、每一个通道都可以通过编程实现左对齐输出还是居中对齐输出。 1、PWM启动寄存器PWME PWME 寄存器每一位如图1所示: 复位默认值:0000 0000B 图1 PWME 寄存器 每一个PWM 的输出通道都有一个使能位P WMEx 。它相当于一个开 关,用来启动和关闭相应通道的PWM 波形输出。当任意的P WMEx 位 置1,则相关的P WM 输出通道就立刻可用。 用法:PWME7=1 --- 通道7 可对外输出波形 PWME7=0 --- 通道7 不能对外输出波形 注意:在通道使能后所输出的第一个波形可能是不规则的。当输出通道 工作在串联模式时(PWMCTL 寄存器中的CONxx置1),那么)使能相应 的16位PWM 输出通道是由PWMEx 的高位控制的,例如:设置

飞思卡尔单片机LED控制例程详解

我的第一个LED程序 准备工作: 硬件:Freescale MC9S08JM60型单片机一块; 软件:集成开发环境codewarrior IDE; 开发板上有两个LED灯,如下图所示: 实验步骤: 1.首先,确保单片机集成开发环境及USBDM驱动正确安装。其中USBDM的安装步骤如下:⏹假设之前安装过单片机的集成开发环境6.3版本:CW_MCU_V6_3_SE; ⏹运行USBDM_4_7_0i_Win,这个程序会在c盘的程序文件夹下增加一个目录C:\Program Files\pgo\USBDM 4.7.0,在这个目录下: 1〉C:\ProgramFiles\pgo\USBDM 4.7.0\FlashImages\JMxx下的文件 USBDM_JMxxCLD_V4.sx是下载器的固件文件; 2〉C:\Program Files\pgo\USBDM 4.7.0\USBDM_Drivers\Drivers下有下载器的usb 驱动 所以在插入usb下载器,电脑提示发现新的usb硬件的时候,选择手动指定驱动 安装位置到以上目录即可。 ⏹运行USBDM_4_7_0i_Win之后,还会在目录: C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.3\prog\gdi 下增加一些文件,从修改时间上来看,增加了6个文件,这些文件是为了在codewarrior 集成开发环境下对usb下载器的调试、下载的支持。

2.新建一个工程,工程建立过程如下: ⏹运行单片机集成开发环境codewarrior IDE ⏹出现如下界面 ●Create New Project :创建一个新项目工程 ●Load Example Project :加载一个示例工程 ●Load Previous Project :加载以前创建过的工程 ●Run Getting started Tutorial:运行CodeWarrior软件帮助文档 ●Start Using CodeWarrior:立刻使用CodeWarrior ⏹点击Create New project按钮,以创建一个新的工程,出现选择CPU的界面 如下,请选择HCS08/HCS08JM Family/MC9S08JM60,在右边的Connection窗口

飞思卡尔系列中DZ60单片机SPI应用程序

飞思卡尔系列中DZ60单片机SPI应用程序 源代码及说明如下: #include /* I/O map for MC9S08DZ60MLH */ #include "MCUinit.h" char TLE7231G(char SIDATA){ //定义驱动TLE7231G的函数,主函数通过参数传递控制驱动的状态 // SENDCHAR(SIDATA); } void SPI_init(void) { //初始化主SPI器件,不同的驱动芯片波特率会有不同。 SPIC1 = 0x57; //01010111 //详细说明见下 SPIC2 = 0x19; //00011010 SPIBR = 0x00; //波特率设置为2000KHZ SPIS = 0x20; //SPI状态寄存器 SPID = 0x00; //SPI数据寄存器 } /* SPI初始化: SPIC1:BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 //SPI控制寄存器1 SPIE SPE SPTIE MSTR CPOL CPHA SSOE LSBFE //标志位 | | | | | | | |------LSB先发(移位器方向) | | | | | | | 0:SPI串行数据传输始于最高位 | | | | | | | 1:SPI串行数据传输始于最低位 | | | | | | |-----------辅选择输出使能 | | | | | | 0:MODFEN=0时,通用I/O口;MODFEN=1时,模式故障的SS输入; | | | | | | 1:MODFEN=0时,通用I/O口;MODFEN=1时,自动SS输出; | | | | | |----------------时钟相位 | | | | | 0:SPSCK上的第一个边沿出现在8周期数据传输的第一个周期的中央 | | | | | 1:SPSCK上的第一个边沿出现在8周期数据传输的第一个周期的起点 | | | | |----------------------时钟极性 | | | | 0:SPI时钟高有效(闲置低态)

相关文档
最新文档