第一篇:PIC单片机报告
PIC单片机实验报告
一、定时器的使用
(1)实验目的:通过学习和实验理解PIC单片机定时器的内部工作原理,学会定时器 初始化配置编程,并能利用实验板对定时器有简单的应用。
(2)实验器材:16位PIC单片机学习板。
(3)实验过程:
1、PIC单片机定时器概述:根据具体器件,dsPIC30F 器件系列提供了几个16 位定时器。这些定时器被指定为Timer1、Timer2、Timer3 ……等。可分为三种类型:A类型时基、B类型时基和C类型时基。
A类型时基:在大多数dsPIC30F 器件上,至少有一个A 类型定时器。通常Timer1 是A 类型定时器。A 类型定时器与其他类型的定时器相比,有下列独特的功能:
可以使用器件的低功耗32 kHz 振荡器作为时钟源工作
可以在使用外部时钟源的异步模式下工作
A 类型定时器独特的功能使它可以用于实时时钟应用(Real-Time Clock,RTC)。16 位定时器模式:在16 位定时器模式下,定时器在每个指令周期递增,直到与预先装入周期寄存器PR1 中的值匹配,然后复位至0,继续计数。当CPU 进入空闲模式时,定时器将停止递增,除非TSIDL(T1CON<13>)位 = 0。如果TSIDL = 1,定时器模块逻辑将继续递增,直到CPU 空闲模式终止。位同步计数器模式:在16 位同步计数器模式下,定时器将在外部时钟信号的上升沿递增,外部时钟信号与内部相位时钟同步。定时器计数,直到等于PR1 中预先装入的值,然后复位至0,继续计数。当CPU 进入空闲模式时,同上。位异步计数器模式:在16 位异步计数器模式下,定时器在外部时钟信号的上升沿递增。定时器计数,直到等于PR1 中预先装入的值,然后复位至0,继续计数。当定时器配置为异步工作模式时,CPU 进入空闲模式,如果TSIDL = 1,则定时器将停止递增。
B类型时基:在大多数dsPIC30F 器件上,如果存在Timer2 和Timer4,它们是B 类型定时器。与其他类型的定时器相比,B 类型定时器有下列独特的功能:
B 类型定时器可以和C 类型定时器相连形成32 位定时器。B 类型定时器的TxCON
寄存器具备T32 控制位,用来使能32 位定时器功能。B 类型定时器的时钟同步在预分频逻辑后执行。为输入捕捉,输出比较/ 简单PWM 模块提供时基
C类型时基:在大多数dsPIC30F 器件上,Timer3 和Timer5 是C 类型定时器。与其他类型的定时器相比,C 类型定时器有下列独特的功能:
C 类型定时器可以和B 类型定时器相连形成32 位定时器。在某个给定的器件上,至少有一个C 类型定时器能够触发A/D 转换。
相关寄存器:要使用定时器,首先要了解定时器相关寄存器,dspic30f4011的定时器相关寄存器有:
以A类时基定时器(Timer1)为例,要用到的相关寄存器有:T1CON(定时器1控制寄存器)、IFS0bits(中断标志状态寄存器)、IPC0bits(中断优先级控制寄存器)、IEC0bits(中断允许控制寄存器)、PR1(定时器初值寄存器)
定时器模式:所有类型的定时器都可以在定时器模式下工作。在定时器模式下,定时器的输入时钟由内部系统时钟(FOSC/4)提供。当使能为该模式时,对于1:1 的预分频器设置,定时器的计数值在每个指令周期都会加1。
通过清零TCS 控制位(TxCON<1>)选择定时器模式。
同步模式控制位TSYNC(T1CON<2>)在该模式下不起作用,因为使用了系统时钟源产生定时器时钟。
定时器初值计算:指令周期=1/(fosc/4),定时器初值=所需定时时间/(指令周期×分频比)
程序代码:
#include “p30f4011.h” void timer_init()
{
T1CON=0X8030;
//预分频256,ton=1,开始计时,其余都为0//清除TMR1的中断标志 //中断优先级为7 //使能中断
//在预分频256模式下,计时1秒
IFS0bits.T1IF = 0;
IPC0bits.T1IP = 7;IEC0bits.T1IE = 1;}
PR1=0x1c20;
void __attribute__((__interrupt__))_T1Interrupt(void)//中断服务程序 {}
void main(){}
TRISE=0x100;
//将LED相连IO口设为输出 //执行定时器1初始化 //PORTE初始化输出为低
IFS0bits.T1IF=0;PORTE++;
//软件清除定时器1中断标志位 //实现每一秒对PORTE加1,用LED显示
timer_init();PORTE=0;
while(1);//程序进入死循环,定时执行定定时器中断程序
二、中断
实验目的:通过学习和实践理解PIC单片机中断的特性及工作原理,学会中断的初始化配置,并能对中断进行简单的应用。
实验器材:16位PIC单片机学习板。
实验过程:
dsPIC30F的中断特性:
多达8 个处理器异常和软件陷阱 7 个用户可选择的优先级
具有多达62 个向量的中断向量表(Interrupt Vector Table,IVT)每个中断或异常源都有唯一的向量 指定的用户优先级中的固定优先级
用于支持调试的备用中断向量表(Alternate Interrupt Vector Table,AIVT)固定的中断入口和返回延时
中断优先级:
(1)可以为每个外设中断源分配7 个优先级之一。
可用的优先级从1 开始为最低优先级,7 级为最高优先级。如果与中断源有关的IPC 位被全部清零,则中断源被有效禁止。
(2)由于特定的优先级会被分配给一个以上的中断请求源,所以在给定的用户分配
级别内提供了一种解决优先级冲突的方法。
根据每个中断源在IVT中的位置,它们都有一个自然顺序优先级。中断向量的编号越低,自然优先级越高,而向量的编号越高,自然优先级越低。
(3)任何待处理的中断源的总优先级都首先由该中断源在IPCx 寄存器中用户分配的优先级决定,然后由IVT 中的自然顺序优先级决定。
相关寄存器:INTCON1 和INTCON2(全局中断控制寄存器)、IFSx(中断标志状态寄存器)、IECx(中断使能控制寄存器)、IPCx(中断优先级控制寄存器)、SR(CPU状态寄存器)、CORCON(内核控制寄存器)。
初始化配置:
1.如果不需要中断嵌套,将NSTDIS 控制位置1。
2.通过写相应的IPCx 控制寄存器中的控制位选择中断源的用户分配优先级。如果不需要多个优先级,所有允许的中断源的IPCx 寄存器控制位均可以编程为同一个非零值。3.在相关的IFSx 状态寄存器中清零与外设相关的中断标志状态位。
4.通过在相应的IECx 控制寄存器中置1 与中断源相关的中断允许控制位,使能中断源。
程序代码:
void init(){
IFS0bits.INT0IF = 0;//清除INT0的中断标志
IPC0bits.INT0IP = 7;//中断优先级为7 IEC0bits.INT0IE = 1;}
void __attribute__((__interrupt__))_INT0Interrupt(void)//中断服务程序 {
IFS0bits.INT0IF = 0;Led=~Led;}
int main(){
unsigned char Led=0;init();while(1){
PORTE = Led;
//清INT0中断标志//实现LED亮灭变化 //使能中断
}}
第二篇:PIC单片机课程设计报告
河北联合大学轻工学院
QINGGONG COLLEGE, HEBEI UNITED UNIVERSITY
《PIC单片机课程设计》
学生姓名: 学号: 学部:专业班级:指导教师:
年月日
一、课程设计目的本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICC C语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。
二、设计题目及要求
2.1 设计题目:
基于PIC16F877单片机的多功能电子时钟 2.2 功能实现:
实时时钟显示,时间可调;实时温度显示,并具有超限报警功能。输出显示采用LCD1602或LED七段数码显示器。2.3 设计要求:
自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus仿真,最终可实现脱机运行。
三、设计原理说明
3.1 时钟模块
DS1307是美国DALLAS公司推出的I2C总线接口实时时钟芯片,它可独立于CPU 工作,不受CPU主晶振及其电容的影响,且计时准确,月累积误差一般小于10秒。芯片还具有主电源掉电情况下的时钟保护电路,DS1307的时钟靠后备电池维持工作,拒绝CPU对其读出和写入访问。同时还具有备用电源自动切换控制电路,因而可在主电源掉电和其它一些恶劣环境场合中保证系统时钟的定时准确性。
DS1307具有产生秒、分、时、日、月、年等功能,且具有闰年自动调整功能。同时,DS1307芯片内部还集成有一定容量、具有掉电保护特性的静态RAM,可用于保存一些关键数据。3.2 显示模块
如用LCD1602作为显示设备,要求显示屏分两行显示,第一行显示日期(年-月-日)和星期,第二行显示时间(时:分:秒)和温度。显示秒由00一直加到59,分钟数也由00加到59,小时采用24小时制,由00加到23,如此循环显示。
3.3 按键模块
按键用来作为时间调整。要求至少设计4个按键,按键1作为设置键;按键
2、按键3分别为增加、减少键,在设置键按下时,此两个按键方有效;按键4是确定键,在设置键按下时方才有效。3.4 温度采集模块
DS18B20是美国DALLAS公司推出的单总线数字温度传感器。DS18B20内部集成了温敏元件、数据转换芯片、存储器芯片和计算机接口芯片等多功能模块。其主要技术特点有:具有独特的单线接口方式;可以通过数据线供电,具有超低功耗工作方式;测温范围为-55℃~125℃,测温精度为0.5℃;温度转换精度9~12位可编程,直接将温度转换值以二进制数码的方式串行输出。
四、硬件原理图
(含原理图、电路仿真图)
五、软件设计
(含流程图、带注释的程序清单)
六、设计总结
设计成绩:
教师签名:
年月
日
第三篇:基于PIC单片机电子万年历实验报告
实验报告
姓名:文可鑫学号:20072121010专业:电子信息工程
1编写一个秒表程序,使用查询方式。
listp=16f877a
include“p16f877a.inc”
include
countequ20h
count_sequ21h
org000h
startnop
callInitSPI
bankselOPTION_REG
movlw04h
movwfOPTION_REG
bankselINTCON
movlw00h
movwfINTCON
movlw06h
movwfTMR0
movlwd'131'
movwfcount
movlw00h
movwfcount_s
mainbtfssINTCON,T0IF
goto$-1
movlw06h
movwfTMR0
bcfINTCON,T0IF
incfcount,f
btfssSTATUS,Z
gotomain
movlwd'131'
movwfcount
incfcount_s,f
movfcount_s,w
sublwd'60'
btfscSTATUS,Z
clrfcount_s
movfcount_s,w
callBin2BCD
movfDIS_TEMP2,w
callCHAR_CODE1
movwfDIS_TEMP2movfDIS_TEMP1,wcallCHAR_CODE1movwfDIS_TEMP1callLEDlightnop
gotomain CHAR_CODE1;共阴极字符表
ADDWF PCL,F
RETLW 3fh;0RETLW 06h;1RETLW 5bh;2RETLW 4fh;3RETLW 66h;4RETLW 6dh;5RETLW 7dh;6RETLW 07h;7RETLW 7fh;8RETLW 6fh;9 Bin2BCD
CLRF DIS_TEMP1MOVWF DIS_TEMP2 Ttenth
MOVLW.10SUBWF DIS_TEMP2,WBTFSS STATUS,CGOTO OUT
MOVWF DIS_TEMP2INCF DIS_TEMP1,FGOTO Ttenth OUT
RETURN
end
2编写一个秒表程序,使用中断方式。listp=16f877a
include“p16f877a.inc” include
gotointp startnop
callInitSPIbankselOPTION_REGmovlw44h
movwfOPTION_REGbankselINTCONmovlw0a0hmovwfINTCONmovlw06hmovwfTMR0movlwd'131'movwfcountmovlw00hmovwfcount_s heregotohere intp
btfssINTCON,T0IFgoto$-1movlw06hmovwfTMR0
bcfINTCON,T0IFincfcount,fbtfssSTATUS,Zgotointpmovlwd'131'movwfcountincfcount_s,fmovfcount_s,wsublwd'60'btfscSTATUS,Zclrfcount_smovfcount_s,wcallBin2BCDmovfDIS_TEMP2,wcallCHAR_CODE1movwfDIS_TEMP2movfDIS_TEMP1,wcallCHAR_CODE1movwfDIS_TEMP1callLEDlightnop
RETFIE
CHAR_CODE1;共阴极字符表
ADDWF PCL,F
RETLW 3fh;0RETLW 06h;1RETLW 5bh;2RETLW 4fh;3RETLW 66h;4RETLW 6dh;5RETLW 7dh;6RETLW 07h;7RETLW 7fh;8RETLW 6fh;9 Bin2BCD
CLRF DIS_TEMP1MOVWF DIS_TEMP2 TtenthMOVLW.10SUBWF DIS_TEMP2,WBTFSS STATUS,CGOTO OUT
MOVWF DIS_TEMP2INCF DIS_TEMP1,FGOTO Ttenth OUT
RETURN
end CHAR_CODE1;共阴极字符表
ADDWF PCL,F
RETLW 3fh;0RETLW 06h;1RETLW 5bh;2RETLW 4fh;3RETLW 66h;4RETLW 6dh;5RETLW 7dh;6RETLW 07h;7RETLW 7fh;8RETLW 6fh;9 Bin2BCD
CLRF DIS_TEMP1MOVWF DIS_TEMP2 Ttenth
MOVLW.10SUBWF DIS_TEMP2,WBTFSS STATUS,CGOTO OUT
MOVWF DIS_TEMP2INCF DIS_TEMP1,FGOTO Ttenth OUT
RETURN
end
listp=16f877a
include“p16f877a.inc” include
callInitSPIbankselOPTION_REGmovlw04h
movwfOPTION_REGbankselINTCONmovlw00hmovwfINTCONmovlw06hmovwfTMR0movlwd'131'movwfcountmovlw00hmovwfcount_s heregotohere
intpbtfssINTCON,T0IFgoto$-1movlw06hmovwfTMR0
bcfINTCON,T0IFincfcount,fbtfssSTATUS,Zgotointpmovlwd'131'movwfcountincfcount_s,fmovfcount_s,w
sublwd'60'btfscSTATUS,Zclrfcount_smovfcount_s,wcallBin2BCDmovfDIS_TEMP2,wcallCHAR_CODE1movwfDIS_TEMP2movfDIS_TEMP1,wcallCHAR_CODE1movwfDIS_TEMP1callLEDlightnop
RETFIE
CHAR_CODE1;共阴极字符表
ADDWF PCL,F
RETLW 3fh;0RETLW 06h;1RETLW 5bh;2RETLW 4fh;3RETLW 66h;4RETLW 6dh;5RETLW 7dh;6RETLW 07h;7RETLW 7fh;8RETLW 6fh;9 Bin2BCD
CLRF DIS_TEMP1MOVWF DIS_TEMP2 Ttenth
MOVLW.10SUBWF DIS_TEMP2,WBTFSS STATUS,CGOTO OUT
MOVWF DIS_TEMP2INCF DIS_TEMP1,FGOTO Ttenth OUT
RETURN
end
第四篇:PIC单片机学习笔记之PWM信号输出
实现功能:通过键盘(BUTTON)控制蜂鸣器发生,键盘按下,通过RC2/CCP1接口输出PWM信号(频率880Hz,脉宽50)驱动蜂鸣器发声。
实验环境: Proteus 编程语言: 汇编 编程环境: MPLAB 单片机: 晶振: PIC16F877 20MHz Proteus仿真电路如图。
实验源程序:
LIST P=16F877;设置pwm为880Hz,50%占空比
INCLUDE P16F877.INC ORG
0000H START
BANKSEL TRISC;进入TRISC所在BANK BCF
TRISC,2;清零TRIC的bit2,以使CCP1引脚成为输出
MOVLW D'70' MOVWF PR2;将70写入PR2以设置PWM周期 BANKSEL CCPR1L MOVLW D'35' MOVWF CCPR1L MOVLW 0X06 MOVWF T2CON;bit2=1,使能Timer2,bit1-1,预分频值为16 CHECKBUTTON BTFSC GOTO
PORTA,4 BUTTONOFF BUTTONON
MOVLW H'0C' MOVWF CCP1CON;设置CCP1为PWM模式 GOTO
CHECKBUTTON BUTTONOFF
CLRF CCP1CON GOTO END
CHECKBUTTON
第五篇:PIC学习心得
PIC学习心得
本次心得为PIC18F25K22上的代码
零、配置CPU 的特殊功能,地址从300000开始,如以下,有晶振选择,复位功能,看门狗配置,调试口rb7-rb6的配置,因为RB6-RB7为串口2的端口,需要对应为位=1才能使得他们可以用于普通io,其实单片机默认也是1.对于已经用于特殊功能的引脚,比如已经配置了引脚为I2C功能,如果要配置为普通IO时,需要将I2C失能掉,SSPXCON1=0X00;这样才能正常使用这2个IO口了
如果要使单片机使用内部晶振,就需要将对应的OSCCON位置1 IRCF<2:0>:内部RC 振荡器频率选择位(2)IRCF<2:0>=111 = HFINTOSC –(16 MHz)OSTS=0 = 器件依靠内部振荡器(HFINTOSC、MFINTOSC 或LFINTOSC)运行 OSCCON2默认
使用内部晶振时,频率会随温度漂移,使用波特率的时候要注意了,最好使用外部晶振
PWDX默认,使外围功能使能
#pragma romdata CONFIG1H=0x300001
//晶振 const rom unsigned char config1H = 0x0a;//setting for HS oscillator中档功耗 #pragma romdata CONFIG2L=0x300002
//复位 const rom unsigned char config2L = 0x00;#pragma romdata CONFIG2H=0x300003 const rom unsigned char config2H = 0x1e;//WDT #pragma romdata CONFIG3H=0x300005//配置一些端口的映射
const rom unsigned char config3H = 0x00;//禁用复位脚,开始为 CPU提供时钟而无需等待
#pragma romdata CONFIG4L=0x300006//最高位为1,RB6 和 RB7用于普通IO口
const rom unsigned char config4L = 0x80;//RB6 和 RB7专用于在线调试 #pragma romdata
一、中断配置,PIC只有高低2个优先级,对应的函数有2个,函数地址为0X08和0X18中断配置,一下为高低优先级配置
RCONbits.IPEN=1;//使能中断优先级,如果IPEN配置为0,没有中断优先级,所有优先级都为高,调到0x08地址的中断
INTCONbits.GIE=1;//=允许所有高优先级中断 INTCONbits.PEIE=1;//=允许所有低优先级的中断
2、中断函数写法 高优先级地址为0X08 #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh(void){
_asm
goto InterruptHandlerHigh
//jump to interrupt routine,goto之后的InterruptHandlerHigh函数名可以自己取名
_endasm } // High priority interrupt routine #pragma code #pragma interrupt InterruptHandlerHigh //InterruptHandlerHigh函数名可以自己取名
void InterruptHandlerHigh()//中断函数内容 低优先级函数地址为0X18 #pragma code InterruptVectorLow= 0x18 void InterruptVectorLow(void){
_asm
goto InterruptHandlerLow //jump to interrupt routine,goto之后的InterruptHandlerHigh函数名可以自己取名
_endasm } // High priority interrupt routine #pragma code #pragma interruptlow InterruptHandlerLow //InterruptHandlerHigh函数名可以自己取名
void InterruptHandlerLow(void)//中断函数内容
3、例如串口中断配置:
IPR1bits.RC1IP=0;//设为低优先级,让他跳入低优先级中断函数,为1将跳入高优先级函数
PIR1bits.RC1IF=0;//清中断标志
PIE1bits.RC1IE=1;//接收中断允许
PIE1bits.TX1IE=0;//发送中断禁止
4、这样配置完成后,如果串口其他寄存器配置无误,接收到数据后就会跳入低优先级函数InterruptHandlerLow中
二、ADC
1、ADC采集为了不浪费MCU资源,不用中断函数来采集 配置如下,(1)先将要用于ADC采集的IO口配置为输入(2)将对应IO扣配置为ADC输入(3)配置ADCON0-3寄存器
TRISA|=0x01;//引脚方向寄存器,1输入,0输出。将对应引脚定义为输入
ANSELA|=0x01;//对应的引脚定义为ADC输入
ADCON1=0b00000000;
//正向参考电压VDD
ADCON2=0b10001101;
//ADC结果右对齐保存,采集时间2TAD,时钟Fosc/16
ADCON0|=0x01;
//使能ADC
1、开始采集(1)、ADCON0&=(~0x7c);ADCON0|=(channel<<2);配置对应的通道(2)、ADCON0bits.GO_DONE=1;开始采集,等他值0后采集完成。uint16 get_ad(uint8 channel)
//数模转换结果AD值
{
uint16 adval;uint8 k;
ADCON0&=(~0x7c);
ADCON0|=(channel<<2);
//配置转换通道
adval=0;for(k=0;k { ClrWdt(); ADCON0bits.GO_DONE=1;//开ADC转换 while(ADCON0bits.GO_DONE);//当ADGO为0表示这次ADC转换完成? adval=adval+((ADRESH&0X03)*256)+(ADRESL);//00000011 11111111 把转换结果的高位和低位放进同一个16位数里面 } adval=adval/ADC_SAMPLETIME; //取样50次,取平均值 return(adval);//将结果返回 } 三、UART配置 1、配置(1)、对应IO口配置为输入TRISC(2)、对应的IO口配置为数字端口ANSELC(3)、配置SYNC=0,使得串口为异步的(4)、配置波特率,公式根据BRG16,BRGH来配置,都=0,公式为((SPBRGH1<<8)| SPBRG1)=Focs/(boad*64)-1;只有一个=1,=Focs/(boad*16)-1;都=1,=Focs/(boad*4)-1。计算完成后如果波特率相差比较远,这个波特率就用不了,比如16M配置115200的波特率,相差很远,通讯内容不正常。(5)、寄存器大部分直接默认为0就好了;发送,接收使能打开,串口使能打开,根据波特率来设置BRG16,BRGH。其他都为0(注:以前打开使能自动波特率模式,发送接收就不正常,他是其他的功能)(6)、配置中断就3个位,中断使能位在PIE寄存器中,中断优先级位在IPR中,中断标志位在PIR中 void Uart1_initial(void)//test { TRISCbits.TRISC7=1;//RX1,将IO两个端口设置为输入 TRISCbits.TRISC6=1;//TX1, ANSELCbits.ANSC7=0;ANSELCbits.ANSC6=0; //自动波特率溢出位1溢出,接收空闲标志位1空闲,接收极性选择位1为低,1发送口空闲为高、// 1使能16为波特率发生器,无,唤醒使能位,自动波特率检测使能位 //BAUDCTL=0b00000000;//??? //((16000000/9600)/64)-1=25;SPBRGH1=0x00; //((16000000/9600)/16)-1=103;SPBRG1 =103;//根据SYNC BRG16 BRGH这3位来判断计算公式,具体看手册//0X19; //9600 25=0X19;////////波特率说明:波特率配置时,先使能外部时钟,16M外部时钟不能设置56k以上波特率,误差很大 RCSTA1=0b10010000;//串口使能 //使能串口,9-8接收位,单字节接收使能(异步无关),连续接收使能,//地址检测使能,帧错误标志位,溢出标志,接收第9为 TXSTA1=0b00100100;//选择异步,高速方式,传输8位数据, //异步无关位,8位,使能发送,异步,发送间隔字符位,高低波特率,发送寄存器满,第9位 //RCONbits.IPEN=1;//使能中断优先级。 //IPR1bits.TX1IP=0;//设为高优先级 BAUDCON1=0b00000000;//自动波特率检测使能不要值1 IPR1bits.RC1IP=0;//设为低优先级 PIR1bits.RC1IF=0;//清中断标志 PIR1bits.TX1IF=0;PIE1bits.RC1IE=1;//接收中断允许 PIE1bits.TX1IE=0;//发送中断禁止 UART1Receive.ReceiveDataLen=0;UART1Receive.IndexPointer=UART1Receive.ProPointer=0;} 四、定时器0 定时器就比较简单了,处理中断的3个位(在INTCON,INTCON2中),就一个控制寄存器T0CON,和2个计数寄存器TMR0H, TMR0L。 1、Timer0预分频的初始时钟=Fosc/4,于是计算的时候不能以FOSC来计算 2、在中断后,如果不需要再中断,失能定时器,失能中断。如果还需要中断,需要将数据再次填入计数寄存器中,并且中断标志清0。配置如下 void Timer0_init(void)//不用作定时器,计风扇周期个数 { //定时器0时钟源为FOSC/4 ////Timer1/3/5 时钟源为FOSC和FOSC/4 T0CON=0b10000111;//开启定时器0,256预分频 TMR0H=0xe7; //TMRX=65536-T*时钟源/分频数,如果定时器0定时1s,fosc=16M的话TMR0=65536-1*16000000/4/256=0xc2f7.//TMR0L=0xdc; //对TMR0写入一个调整值,因为写入TMR0后接 TMR0L=0x96; //着的两个周期不能增量,中断需要3个周期的响应 //时间,以及C语言自动进行现场保护要消耗周期 INTCONbits.TMR0IE=1;//中断允许 INTCONbits.TMR0IF=0;//中断标志 INTCON2bits.TMR0IP=0;//优先级为低,然后再低优先级函数通过中断标志写上对应的函数就可以了 } 五、I2C 参考百度中的笔记 #pragma udata DataArray5 //一个数据块的开始 uint8 I2CCommuSaveBuf[SaveBufLen];//通讯缓冲区 #pragma udata //一个数据块的结束 PIC的一个块为256个字节,不能定义比这个更长的数组了。如果直接定义一个256数组,编译器可能会出错,需要以上配置成一个块才可以用 六、外部触发中断 void ExternINT0_Init(){ TRISBbits.TRISB0=1;//将IO两个端口设置为输入 PORTBbits.RB0=0;ANSELBbits.ANSB0=0;//数字信号 INTCON2bits.INTEDG0=1;//上升沿中断,0=下降沿中断 INTCONbits.INT0IF=0;//中断清0 INTCONbits.INT0IE=1;//中断使能 //没有优先级位,跳高优先级中断 } void ExternINT1_Init(){ TRISBbits.TRISB1=1;//将IO两个端口设置为输入 ANSELBbits.ANSB1=0;//数字信号 PORTBbits.RB1=0;INTCON2bits.INTEDG1=1;//上升沿中断,0=下降沿中断 INTCON3bits.INT1IF=0;//中断清0 INTCON3bits.INT1IE=1;//中断使能 INTCON3bits.INT1IP=0;//优先级低 } 七、内部EEPROM读写 对于18F25K22:EEADR 寄存器用于寻址数据EEPROM 以进行读写操作。8 位的寄存器可寻址256 字节(00h 至FFh)的存储器范围。通过增加2个额外的地址位,EEADRH 寄存器将范围扩展到1024 字节。以下为256字节的EEPROM读写 u8 EEPROM_ReadOneData(u8 readADD){ PIE2bits.EEIE=0;//将中断失能掉 EEADR=readADD;//写入地址。//也可以EEADRH= readADD>>8,EEADR= readADD,(readADD需要16位),来实现1024字节的读 EECON1bits.CFGS=0;//访问闪存程序存储器或数据EEPROM 存储器 EECON1bits.EEPGD=0;//访问数据EEPROM 存储器 EECON1bits.RD=1;//启动EEPROM 读操作 Nop();Nop();//等待读取完成,读EEPROM是很快的return(EEDATA);} void EEPROM_WriteOneData(u8 WriteADD,u8 WriteData){ PIE2bits.EEIE=0;//将中断失能掉 EEADR=WriteADD;//也可以EEADRH= readADD>>8,EEADR= readADD,(readADD需要16位),来实现1024字节的写 EEDATA=WriteData;//放入要写入的数据 EECON1bits.CFGS=0;//访问闪存程序存储器或数据EEPROM 存储器 EECON1bits.EEPGD=0;//访问数据EEPROM 存储器 //EECON1bits.EEPGD=0;//访问数据EEPROM 存储器 EECON1bits.WREN=1;//写使能 EECON2=0x55;//写操作命令 EECON2=0xaa;//这两句话是必须的 EECON1bits.WR=1;//开始写操作,必须先使能写WREN位,再开启写操作 //WR由硬件清0 while(!PIR2bits.EEIF);//等待写完成PIR2bits.EEIF=0;//必须软件清0 EECON1bits.WREN=0;//写失能 } 八、18B20读温度 1、首先初始化设备,根据以上时序图,先将对应脚输出置高,然后置低,保持480-960US,然后再置高,设置引脚输入等待18B20应答:等待18B20置低15-60US,再等待置高60-240us。 2、写命令:写入0xcc,这个命令允许总线控制器不用提供64位ROM编码就使用功能指令。然后写入0x44,开始转换温度。每写一个位如上图所示,先将端口输出置高>1US-置低,维持>1US,然后写入该位,等待18B20接收数据,维持15-45US,再写下一位 3、读命令:先要将总线输出置高>1us,置低,维持1-10us。然后读入数据,等待15-45US,在读下一位 4、读温度:每次发命令之前,需要将首先初始化设备,然后写入指令。比如每次读一次温度顺序:初始化-写入0XCC(不用提供64位ROM编码使用)-写入0X44(开始温度转换)-初始化-写入0XCC-写入0XBE(读温度指令)-读温度字节低-读温度字节高=完成。 九、PWM设计 //////////////////////////////////////////////////////////////////////////// //说明:18f25k22有5个10位CCP,CCP2和CCP3需要通过配置config3H_image和config3H定义输出脚 //PWM配置,如果2个ccp用一个定时器,那么他们2个的PWM周期是必定一样 //但是他们的占空比可以分别调制 /////////////////////////////////////////////////////////////////////////// 以下对CCP2进行解说: 1、首先你需要将CCP口映射到其他端口上需要将特殊寄存器config3H对应位置1 2、将对应的端口设置为输入 3、选择CCP需要的定时器,他是在2/4/6定时器选择 4、设置定时器周期,5、配置定时器,CCP不需要中断,根据实际情况配置器分频,使能 6、配置占空比 7、在程序运行过程中需要调节占空比,配置CCP2CON的4-5位为10位的第2位,CCPR2L为10位的高8位。如: CCP2CON|=((receivebuf[2]&0x03)<<4); CCPR2L=receivebuf[1];以下为CCP2实用定时器4的配置: void CCP2_PWM_init(void){ u8 tem1;tem1=config3H_image;if(!(config3H_image&0x01)) TRISB|=0x08;//手册说设置为输入,输出在PB3,根据CONFIG3H else TRISC|=0x02;//手册说设置为输入,输出在PC1 CCPTMRS0&=(~0B00010000);//使用定时器4 CCPTMRS0|= 0B00001000;//使用定时器4 PR4=0Xff;//设置pwm工作周期 //PWM频率=Fosc/4/(PRX+1)/(TMR2预分频值)CCP2CON=0x0f;//PWM模式,占空比低2位为0 CCPR2L=0x80;//占空比高8位 //占空比=(CCPR1L*4+CCP1CON<5,4>)/(4*(PRx + 1)) //因为PWM是用定时器246来做的,一下配置用到的2、4、6定时器 T4CON=0B00000100;//预分频为1/4 ,使能定时器2 //T4CON=0B00000111; //0000 0100 //T4CON=0X04; //打开TMR2,且使其前后分频为1,同时开始输出PWM波形 PIE2bits.CCP2IE=0;//禁止CCP2中断 PIE5bits.TMR4IE=0;//失能定时器4中断 PIR5bits.TMR4IF=0;//清定时器4中断标志 while(!PIR5bits.TMR4IF);if(!(config3H_image&0x01)) TRISB&=(~0x08);//最后将端口设置为输出,输出在PB3 else TRISC&=(~0x02);//最后将端口设置为输出,输出在PC1 } 十、普通IO配置 本以为普通IO口配置是很简单的,但是实际用起来之后才发现并不是那样的,普通IO口无论是输入还是输出都需要配置TRISX方向寄存器,和ANSELX模拟IO口,ANSELX默认是1,也就是说ANSELX默认是模拟IO口,除了我们用到ADC或者DAC时才ANSELX=1;其他情况下都要添加ANSELX=0语句。 TRISB|=0x21;//0x21pgin,protetion ANSELB&=(~0x21); TRISA|=0x01;//pson ANSELA&=(~0x01); //out TRISC&=(~0x87);//0,1,2,7 ANSELC&=(~0x87); TRISA&=(~0xfc);// 2,3,4,5,6,7 ANSELA&=(~0xfc); TRISB&=(~0x14);// 2.4 ANSELC&=(~0x14);// 2.4