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

合集下载

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

飞思卡尔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启动寄存器PWMEPWME 寄存器每一位如图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 的高位控制的,例如:设置PWMCTL_CON01 = 1,通道0、1级联,形成一个16位PWM 通道,由通道 1 的使能位控制PWM 的输出。

飞思卡尔单片机快速上手指南说明书

飞思卡尔单片机快速上手指南说明书

Freescale Semiconductor, Inc.Document Number: 用户指南 Rev. 0, 09/2014Confidentiality statement, as appropriate to document/part status.___________________________________________________________________飞思卡尔单片机快速上手指南作者:飞思卡尔半导体IMM FAE 团队飞思卡尔半导体是全球领先的单片机供应商,其单片机产品包含多种内核,有数百个系列。

为支持用户使用这些产品,飞思卡尔提供了丰富的网站资源、文档及软硬件工具,另外,我们还有众多的第三方合作伙伴及公共平台的支持。

对于不熟悉飞思卡尔产品和网站的初学者来说,了解和使用这些资源这无疑是一个令人望而生畏的浩瀚工程。

本指南的目的,就是给初学者提供一个指导,让他们不被这些海量信息淹没;用户根据本指导提供的操作步骤,能迅速找到所需的资源,了解如何使用相关的工具。

在本指南中,我们以飞思卡尔的新一代Kinetis 单片机K22系列为例,介绍了如何获取与之相关的资源,如何对其进行软硬件设计和开发。

实际上,这些方法也适用于其它的单片机系列。

当然,对于其它有较多不同之处的产品,我们也会继续推出相应的文档,供广大用户参考。

目录1 如何获取技术资料与支持 ..........................................................2 2 如何选择产品、申请样片及购买少量芯片和开发工具 ........... 93 飞思卡尔单片机的开发环境、开发工具和生态系统 ............. 224 如何阅读飞思卡尔的技术文档 ................................................ 45 5 飞思卡尔单片机硬件设计指南 ................................................ 55 6飞思卡尔单片机软件开发指南 (67)飞思卡尔单片机快速上手指南, Rev. 1, 09/20142Freescale Semiconductor, Inc.1 如何获取技术资料与支持1.1 概述当用户使用飞思卡尔单片机芯片时,如何获取芯片的数据手册(Datasheet )、参考设计(Reference Manual )和官方例程等资源呢?另外当用户遇到了技术问题该如何获得帮助和解答呢?这里以Kinetis 的K22系列芯片为例为大家介绍如何解决这些问题。

飞思卡尔程序

飞思卡尔程序

飞思卡尔程序#include <hidef.h> /* common defines andmacros */#include <mc9s12dg128.h> /* derivativeinformation *///#include "PWM.h"//#include "AD.h"#include "control.h"#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"word AD_wData[9]; //全局变量存放 AD0,AD1,AD2的结果word sum[9]; //初始化时为求平均值,全白中,各个灯的FF次的电压和word avrg0[9]; //全白时各个灯的平均电压word summ[9];//初始化时为求平均值,全黑中,各个灯的FF次的电压和word avrg1[9]; //全黑时各个灯的平均电压word ss[9]; //实际采集来的各个灯的电压word s[9]; // 实际采集来的各个灯的电压word sum2[8];//用于存放两两灯电压之和word k; //用于存放比较出的最大值uint h=1500;//转角大小int flag = 0;//标志中间灯是否第一次在黑道附近int flagg=0;//标志0灯从哪边感应到黑道int flagg1=0;//标志8灯从哪边感应到黑道int flagg0=0;//标志是左边还是右边出道int j=0;dword i;dword m;dword s0;dword s1;dword p11=0;//以下四个变量用于记录黑道处于同一侧的时间dword p12=0;dword p21=0;dword p22=0;word max0[9]=0;//初始化时采集来的黑道的值int g=0;//为过滤算法使用word cha[9];//用来存放黑白电压差int ffgg0=0;//标志是否用中间板采的数据int ffgg1=0;//标志是否用中间板采的数据word sum0=0; //初始化时采集来9个灯的全白电压和//word sum1=0; //实际采集来的左4个灯的电压和//word sum22=0; //实际采集来的右4个灯的电压和int fla=0;//标志是出道还是入道void AD_Init();void PWM_Init();void PWM_Init1();//void PID();void AD_Init(void) //AD初始化{//控制寄存器2:上电,标志位快速清零,开中断ATD0CTL2 =(ATD0CTL2_ADPU_MASK|ATD0CTL2_AFFC_MASK|ATD0CTL2_ASCIE_MASK) ;ATD1CTL2 =(ATD1CTL2_ADPU_MASK|ATD1CTL2_AFFC_MASK|ATD1CTL2_ASCIE_MASK) ;//控制寄存器3:转换序列长度为3ATD0CTL3 =0x78;//(ATD0CTL3_S2C_MASK|ATD0CTL3_S1C_MASK);ATD1CTL3 =0x78;//(ATD1CTL3_S2C_MASK|ATD1CTL3_S1C_MASK);//控制寄存器4:ATD0CTL4 =(ATD0CTL4_SRES8_MASK|ATD0CTL4_PRS1_MASK|ATD0CTL4_PRS0_MASK) ;ATD1CTL4 =(ATD1CTL4_SRES8_MASK|ATD1CTL4_PRS1_MASK|ATD1CTL4_PRS0_MASK) ;//控制寄存器5:ATD0CTL5 =(ATD0CTL5_DJM_MASK|ATD0CTL5_SCAN_MASK|ATD0CTL5_MULT_MASK);ATD1CTL5 =(ATD1CTL5_DJM_MASK|ATD1CTL5_SCAN_MASK|ATD1CTL5_MULT_MASK); ATD0DIEN=0x00; // 禁止数字输入缓冲ATD1DIEN=0x00; // 禁止数字输入缓冲}#pragma CODE_SEG NON_BANKED //中断服务程序#pragma TRAP_PROCvoid interrupt 22 Int_AD0(void){AD_wData[0] = ATD0DR0; //将结果寄存器中的值存放到数组中AD_wData[1] = ATD0DR1; //将结果寄存器中的值存放到数组中AD_wData[2] = ATD0DR2; //将结果寄存器中的值存放到数组中AD_wData[3] = ATD0DR3;AD_wData[4] = ATD0DR4;AD_wData[5] = ATD0DR5;AD_wData[6] = ATD0DR6;AD_wData[7] = ATD0DR7;AD_wData[8] = ATD1DR0;}#pragma CODE_SEG DEFAULTword max(word a,word b,word c,word d,word e,wordf,word r,word w) {word maxx=0;if(a>maxx)maxx=a;if(b>maxx)maxx=b;if(c>maxx)maxx=c;if(d>maxx)maxx=d;if(e>maxx)maxx=e;if(f>maxx)maxx=f;if(r>maxx)maxx=r;if(w>maxx)maxx=w;return maxx;}void delay0(){for(i=0;i<0xFFFF;i++)for(m=0;m<0x05;m++);}void delay1(){for(i=0;i<0xFFFF;i++);// for(i=0;i<0xFFFF;i++);}void main(void){AD_Init(); //AD 初始化DDRB = 0xFF;DDRA_BIT6=0; //A_BIT6口作为第二块板左边传感器的输入口 DDRA_BIT7=0; //A_BIT7口作为第二块板右边传感器的输入口 PORTB = 0xFF;p=0;for(j=0;j<9;j++){AD_wData[j] = 0; //全局变量初始化sum[j]=0;avrg0[j]=0;avrg1[j]=0;summ[j]=0;}for(j=0;j<9;j++) {max0[j]=0;ss[j]=0;}for(j=0;j<8;j++)sum2[j]=0;EnableInterrupts; //开AD中断for(i=0;i<0xFFFF;i++);for(i=0;i<0xFF;i++) //只能是FF,防止下面sum溢出 {for(j=0;j<9;j++)//采集白道路信息{sum[j]=sum[j]+AD_wData[j];}}for(i=0;i<9;i++) {sum0=sum0+sum[i]/0xFF;avrg0[i]=sum[i]/0xFF;}PORTB=sum[0]/0xFF; //显示0通道采集到的值delay0();PORTB=0x00;//显示马上得进行黑道信息采集了delay1();for(j=0;j<9;j++){for(m=0;m<0xFF;m++){summ[j]=summ[j]+AD_wData[j];}avrg1[j]=summ[j]/0xFF;PORTB=avrg1[j]; //显示采来的黑道信息cha[j]=avrg1[j]-avrg0[j];delay0();PORTB=0x00; //显示马上得进行下一次黑道信息采集了 delay1();}PORTB=0x00;//灯全亮,提示车马上就可以跑了delay1();PWM_Init() ;PWM_Init1(1500,1,200);for(i=0;i<0xFFF;i++);// delay1();for(;;){int f=0;u3=100;if(flagk1==1){p21=0;flagk2=0;p11++;if(p11==0xFFF)flagkk1=1;}else if(flagk2==1){p11=0;flagk1=0;p21++;if(p21==0xFFF)flagkk2=1;}for(f=0;f<9;f++){s[f]=AD_wData[f];ss[f]=s[f]-(avrg0[f]-0x50); //当前值减去初始白道值,以便比较}for(f=0;f<8;f++)sum2[f]=ss[f]+ss[f+1]; //两两灯电压之和//减去1.6V防止溢出*******************if(AD_wData[0]<0xC0&& AD_wData[1]<0xC0&&AD_wData[2]<0xC0&&AD_wData[3]<0xC0&&AD_wData[4]<0xC0&&AD_wData[5]<0xC0&&AD_wData[6]<0xC0&&AD_wD ata[7]<0xC0&&AD_wData[8]<0xC0){if(sum2[0]<0xC0&&sum2[1]<0xC0&&sum2[2]<0xC0&&sum2[3]<0xC0&&sum2[4]<0xC0&&sum2[5]<0xC0&&sum2[6]<0xC0&&sum2[7]<0xD0){fla=1;if(flagg0==1){for(i=0;i<0xFF;i++);PWM_Init1(1140,u1,200);flagk1=1;flagkk2=0;for(;;){if(AD_wData[4]>0xB0||AD_wData[5]>0xB0||AD_wData[6]>0xB0|| AD_wData[7]>0xB0||AD_wData[8]>0xB0){flagg0=0;break;}}}else if(flagg0==2){for(i=0;i<0xFF;i++);PWM_Init1(1860,u1,200);flagk1=0;flagkk2=1;for(;;)if(AD_wData[0]>0xB0||AD_wData[1]>0xB0||AD_wData[2]>0xB0||AD_wData[3]>0xB0||AD_wData[4]>0xB0){flagg0=0;break;}}}else{}}else{if(s[0]-(avrg0[0]-0x13)<0x40 &&s[1]-(avrg0[1]-0x13)<0x40 &&s[2]-(avrg0[2]-0x13)<0x40 && s[3]-(avrg0[3]-0x13)<0x40 &&s[4]-(avrg0[4]-0x13)<0x40 && s[5]-(avrg0[5]-0x13)<0x40 &&s[6]-(avrg0[6]-0x13)<0x40 && s[7]-(avrg0[7]-0x13)<0x40 &&s[8]-(avrg0[8]-0x13)<0x40)///////////注意调整该值36***************{/* if(PORTA_BIT6!=0||PORTA_BIT7!=0){if(PORTA_BIT6!=0&&PORTA_BIT7==0)PWM_Init1(1900,200,1);else if(PORTA_BIT7!=0&&PORTA_BIT6==0)PWM_Init1(1100,200,1);}*/}else{k=max(sum2[0],sum2[1],sum2[2],sum2[3],sum2[4],sum2[5],sum2[ 6],sum2[7]);//谁两和最大,黑道就在谁两之间if(k==sum2[0]){p=0;flagg0=2;if(fla==1)control_11();else if(fla==0) control_1();}else{if(k==sum2[1]){p=0;p1=0;fla=0;control_2(s[1],s[2],ss[1],ss[2],cha[1],cha[2],avrg0[1],avrg 0[2]);}else{if(k==sum2[2]){p=0;p1=0;fla=0;control_3(s[2],s[3],ss[2],ss[3],cha[2],cha[3],avrg0[2],avrg 0[3]);}else{if(k==sum2[3]){p=0;p1=0;fla=0;control_4(s[3],s[4],ss[3],ss[4],cha[3],cha[4],avrg0[3],avrg 0[4]);}else{if(k==sum2[4]){fla=0;p1=0;control_5(s[4],s[5],ss[4],ss[5],cha[4],cha[5],avrg0[4],avrg 0[5]);}else{if(k==sum2[5]){fla=0;p1=0;control_6(s[5],s[6],ss[5],ss[6],cha[5],cha[6],avrg0[5],avrg 0[6]);}else{if(k==sum2[6]){p=0;p1=0;fla=0;control_7(s[6],s[7],ss[6],ss[7],cha[6],cha[7],avrg0[6],avrg 0[7]);}else{if(k==sum2[7]){p=0;flagg0=1;if(fla==0)control_8(); elseif(fla==1)control_88(); } else{}}}}}}}}}}}}。

飞思卡尔8位单片机MC9S0813程序LCD编程C语言程序例

飞思卡尔8位单片机MC9S0813程序LCD编程C语言程序例
*功 能:初始化Lcd(HD44780),设置显示方式,清屏,AC自动+1 *
*参 数:无 *
*返 回:无 *
*-----------------------------------------------------*/
void LcdInit(void)
{
unsigned char i;
LcdData_D=0b11111111; //数据口为输出
Lcd_Command(0b00010100); //光标右移一个字符位,AC自动加1
Lcd_Command(0b00001100); //开显示,关光标显示,不闪烁
}
/*Lcd_Command:执行给定的cmd命令------------------------*
*功 能:执行给定的cmd命令,且延时 *
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(0b10000000); //后7位为DDRAM地址0x00
LcdCtrl|=1<<LcdRS;//RS、R/W=10,写数据到DDRAM中
LcdCtrl&=~(1<<LcdRW);
LcdData=cmd;//把指令码送到Lcd数据传送口
LcdCtrl|=(1<<LcdE); //Lcd开始接收数据
asm("NOP");
asm("NOP");
asm("NOP");
LcdCtrl&=~(1<<LcdE); //Lcd结束接收数据

飞思卡尔单片机SCI通信程序

飞思卡尔单片机SCI通信程序
SCI通信
一、飞思卡尔单片机DZ60 SCI通信
(一)查询发送
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define LED_D1 PTDD_PTDD0
LED_D1_DIR = 1;
LED_D1 = LED_OFF;
//以下为设置波特率,以及初始化SCI1控制寄存器
SCI1BDH = 0X00;
SCI1BDL = 0X68;//波特率设置为9600
SCI1C1 = 0x00; //设置SCI1为正常模式,八位数据位,无奇偶校验
SCI1C2 = 0x0C; //RE = 1(bit2)接收器打开
/*************************************************************/
/*初始化总线时钟PEE模式*/
/*外部晶振频率为4MHz,总线频率16MHz */
/*************************************************************/
for(j = 0; j < 4000; j++);
}
void main(void)
{
DisableInterrupts;
SOPT1 = 0;
INIT_MCG();
EnableInterrupts; /* enable interrupts */
/* include your code here */

飞思卡尔智能车dg128单片机控制程序代码

飞思卡尔智能车dg128单片机控制程序代码
}
void AD_Init(void)
{
ATD0CTL2=0xC0; //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止
ATD0CTL3=0x44; //每次转换8个序列, FIFO, Freeze模式下继续转
ATD0CTL4=0x02; //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz
//设置舵机
PWMCTL_CON01=1; //使得通道0,1成为16位pwm
PWMPER0 =0x75;
PWMPER1 =0x30; //舵机的频率是: 24M/8/30000=100Hz,T=10ms
PWMDTY01=4500; // 对应为4500/30000的占空比,待调整
Infrared_detect();
data_handle();
motor_ctl();
steer_ctl();
}
}
void interrupt 26 MDC_ISR(void)
{
static unsigned int number_count=0; static unsigned int start=0; static
go=2;
if(begin>=150)
go=3;
}
}
}
//-----系统初始化-----------------------
void system_init(void) //system initiat
void speed_ctl(void); //速度控制
void motor_ctl(void); //电机控制
void PACBInit(void);

飞思卡尔单片机S12使用方法及程序

飞思卡尔单片机S12使用方法及程序

飞思卡尔单片机S12使用方法及程序单片机简介: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 #3STAB REFDVLDAB #4STAB SYNRBRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率BSET CLKSEL,#$80}}/******************系统时钟初始化****************/void Init_System_Clock(){asm { // 这里采用汇编代码来产生40M的总线LDAB #3STAB REFDVLDAB #4STAB SYNRBRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率BSET CLKSEL,#$80}上面的代码是汇编写的,这个因为汇编代码量比较少,所以用它写了,具体含义注释已经给出,主函数中调用此函数即可完成时钟初始化,总线时钟为40M.2、SCI模块初始化单片机电路做好了当然少不了和PC之间的通信,通信通过单片机串口SCI链接到PC 端的COM口上去。

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

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

//接受 1 个 8 字节数据函数
char STAT,CHR; STAT=SPIS; if(STAT&0x10) renturn 0x10; else CHR=SPID; return CHR;
}
/* */
//读 SPIS 状态寄存器 //00100000 进行位与,SPIS_MODF 为 1 说明模式错误 //返回错误信息
//若使 TLE7231G 工作在休眠模式,则 RESET 引脚送
*/
/*
初始化 TLE7231
*/
/*
TLE7231G 输入输出数据协议:
SI--输入寄存器
SI_DATA:BIT7BIT6 BIT5BIT4 BIT3BIT2 BIT1BIT0 //输入数据字节
IN3
IN2
IN1
IN0 -----INn 指第 n 通道的模式
0 1 1--------------------------------4
1 0 0--------------------------------5
1 0 1--------------------------------6
1 1 0--------------------------------7
| | |--------------------------------SPI 发送中断使能
||
0:禁止从 SPTEF 中中断(使用
轮询)
||
1:当 SPTEF 为 1 时,请求硬件
中断
| |-------------------------------------SPI 系统使能
|
0:SPI 系统禁止
0:在等待模式中,SPI 时钟继
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

流水灯四种效果:#include <hidef.h> /* common defines and macros */ #include <stdlib.h>#include <mc9s12xdp512.h> /* 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<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(1<<c);}}void effect2() {unsigned char c;for(c=0;c<=6;c++) {delay();PORTB = ~(3<<c);}for(c=7;c>=1;c--) {delay();PORTB = ~(3<<c);}}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寄存器的解释参见书本P113DDRA=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:}}}//行扫描法1unsigned char key_scan(){ unsigned char x,i,temp,row=4,col=4,key=16;//PUCR|=0x01; //等同于PUCR=PUCR|0x01,PUCR寄存器的第0位设置为1,即允许PORTA端口的上拉电阻。

PUCR寄存器的解释参见书本P113DDRA=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,其他三条行线输出1x=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,分频系数250PWMCLK = 0x01; //通道0选择SA作为PWM时钟PWMPER0 = 200; //通道0周期寄存器设置为200PWMDTY0 = 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(); //初始化堆栈指针SPmain();}输入捕捉(求占空比):#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */ #include<MC9S12XS128.h>#include<string.h>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 NONBANKEDvoid 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 NONBANKEDvoid 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 <hidef.h>#include <string.h>#include "IO_Map.h"//#include "derivative.h"// global variables definitionsstatic 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 DEFAULTstatic void WriteToSCI0(const char *text){while (*text != '\0'){while (!(SCI0SR1 & 0x80)); // wait for output buffer emptySCI0DRL = *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_BANKEDvoid interrupt 20 SCI0_ISR(void){unsigned char rc;rc = SCI0SR1; // dummy read to clear flagsrc = SCI0DRL; // data readif(rc!=0x0d)cmd_buf[pos++]=rc;elseexecute_cmd();SCI0DRL = rc;}#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid setbusclock(void){CLKSEL=0X00; // disengage PLL to systemPLLCTL_PLLON=1; // turn on PLLSYNR=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 11REFDV=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 DEFAULTstatic 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];}}}。

相关文档
最新文档