首页 > 技术文章 > pic18f46j50一些驱动总结

zhihui-3669 2020-06-04 20:23 原文

直接上源代码,包括PWM,Capture.pic18f26j50,pic18f系列通用

eccpCatpure.c

#include"sysAll.h"
#include <xc.h>
#include <plib.h>
void capture2Init(void);
void capture2Start(void);
void capture2Close(void);
/******************************************************************************
**Code
******************************************************************************/
/** void capture2Init(void);
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/
void capture2Init(void)
{

 

TRISA1 = 1; //设置为输入
CCP2IE = 0;
CCP2IF = 0;
CCP2IP = 1; //优先级设置为高
CCP2CON = 0;
CCP2CONbits.CCP2M = 0X04; //falling edge capture Mode;5,rising
RPINR8 = 1; //IC2R<4:0>此处选择RP1.可以选择多任意一个RPx作为输入捕获
PPSLock(); //锁住Io remap
TCLKCON = 0X12; //OK,选Timer3,PWM也用到此寄存器不可乱改
TMR3H = 0;
TMR3L = 0;
T3CON = 0B00000011;//crystal driver on ,RD16,TMR3ON = 1;
CCPR2H = 0;
CCPR2L = 0;
}


/** void captureStart(void);
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/
void capture2Start(void)
{
PIE2bits.CCP2IE = 1; // Enable the interrupt
}
/** void captureClose(void);
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/
void capture2Close(void)
{
PIE2bits.CCP2IE = 0; // disEnable the interrupt

}

主程序main函数文件:

#include"sysAll.h"
#include <xc.h>
#include <plib.h>
#include <math.h>
#include <stdio.h>
// #pragma config statements should precede project file includes./编译配置报表应先于项目文件包括。
// Use project enums instead of #define for ON and OFF. /项目使用枚举而不是#定义和关闭。
/*配置位*/
#pragma config DEBUG=ON //必须使能DEBUG,否则调试有异常
#pragma config XINST=OFF //不使用扩展指令集

#pragma config PLLDIV=3 //Oscillator divided by 3 (12 MHz input)
#pragma config OSC=HS //High-Speed Crystal/Resonator mode,PLL always disabled, crystal/resonator connected between RA6 and RA7
/*直接试用晶振,是否使用倍频;ON为使4倍频OFF为关闭倍频,
对于EC 和HS 模式,可以使用PLLEN(软件)或PLLCFG (CONFIG1H<4>)位来使能PLL。对于 INTIOx 模式(HF-INTOSC):
1.有PLLEN 可以使能PLL(PLLCFG 会被忽略)。
2.当振荡器配置为内部振荡器(FOSC<3:0> = 100x)时,只有在HF-INTOSC 频率为4、8 或16 MHz 时才能使能PLL。。*/、

#pragma config DSBOREN=OFF //关闭欠压复位,BOREN=OFF;BODEN=OFF为PIC16F877A的欠压复位使能端。
#pragma config WDTEN=OFF //关闭看门狗
#pragma config WDTPS=256 //WDT后分频比为1:256约为1.024S
#pragma config STVREN=ON //堆栈下溢、满不会导致复位
// CONFIG5L//看门狗关闭 上电延时定时器打开 低电压复位禁止 没有代码保护
#pragma config CP0=OFF //代码保护关闭/代码保护00800-01fff(禁用)
#pragma config WPCFG=OFF //不写保护/不写保护00800-01FFF-03FFF(禁用)
#pragma config WPDIS=OFF

/********************************************************************************************/
//宏定义时钟频率4.0Mhz
/*子函数定义*/
void delayms(uint ms);
static void sys_init(void);
extern void USART1Init(void);
unsigned char msg[] = "Hello\r\n";
uchar T1count = 0, rx1_cnt = 0;
uchar rx1_buf[USART_CONTS_MAX] = { 0x00 };
unsigned int capCont = 0;
u16Union_t captureDataOrig[CAPTCONTMAX];
uchar portbData = 0;
/** 主函数main
*
*/
void main(void)

uint i;
sys_init();
while (1)
{
delayms(50);
PORTBbits.RB4 = !PORTBbits.RB4;
USART1Send(msg, 7);
delayms(50);
}
}
/*
延时ms子函数
以10ms为单位
*/
void delayms(uint ms)
{
uint i;
TMR1IE = 0;
TMR1IF = 0;
for (i = 0; i<ms; i++)
{
TMR1L = 0xC0;
TMR1H = 0x63; // 10ms //按照4MHZ实测准确
T1CON = 0B00000111;
while (!TMR1IF);
TMR1IF = 0; //必须软件清零
T1CONbits.TMR1ON = 0;
}
T1CON = 0B00000110;
}

/** static void tmr0_init(void)
*
*/
static void tmr0_init(void)
{
TMR0L = 0xDF;//5ms
TMR0H = 0xB1;
T0CON = 0b00001000;
T0CONbits.TMR0ON = 1;
}

/** static void sys_init(void)
*
*/
static void sys_init(void)

ANCON0 = 0XFF;//先禁止掉ADC功能,设置为io功能
ANCON1 = 0X1F;
PORTB = 0xFF;
RCON = 0x80; //0x80;IPEN=1 interrupt priority enble,
IPR1bits.RCIP = 1; //优先级设置 0,低优先级
INTCON2bits.TMR0IP = 0; //优先级设置 1,低优先级
CCP2IP = 1; //优先级设置 1,
CCP1IP = 1; //优先级设置 1,
//INTCON2=0x00; //中断使能设置,0禁止;1使能
/****B4端口方向设置,0是输出****/
TRISB4 = 0; // led, 0是输出!
TRISB5 = 0; // led, 0是输出!

INTCON = 0b11110000;//INT0 IE=1打开全局中断,TIM0中断
tmr0_init();
USART1Init();
PWM_Init();
capture2Init();
capture2Start();
}


/** void interrupt high_isr (void)
* 串口1 接收数据中断
*/
void interrupt high_priority high_isr(void)
{
if (PIR1bits.RC1IF == 1)
{
rx1_buf[rx1_cnt] = RCREG1;
if (rx1_cnt < USART_CONTS_MAX)
{
rx1_cnt++;
}
PIR1bits.RC1IF = 0;
}

if (CCP2IF == 1)
{
CCP2IF = 0;
if (capCont < CAPTCONTMAX)
{
captureDataOrig[capCont].m_u8Array[1] = CCPR2H;
captureDataOrig[capCont].m_u8Array[0] = CCPR2L;
capCont++;
}
else
{
capCont = 0;
}
if ((CCP2CON & 0x0f) == 0x04)//目前这种方式造成不准确。
{
CCP2CONbits.CCP2M = 0X05; //上升沿
}
else
{
CCP2CONbits.CCP2M = 0X04;//下降沿
}
TMR3H = 0;
TMR3L = 0;
}
if (INT0IF) //总是高优先级
{
INT0IF = 0;
}
}

/** void interrupt high_isr (void)
* T0 中断
*/

void interrupt low_priority low_isr(void)
{
if (PIR1bits.TMR2IF == 1)
{
PIR1bits.TMR2IF = 0;
}
if (INTCONbits.TMR0IF == 1)
{
TMR0L = 0xDF;//5ms
TMR0H = 0xB1;
T1count++;
if (T1count>50)
{
T1count = 0;//1500ms
RB5 = !RB5;
}
INTCONbits.TMR0IF = 0;
}

if (RBIF == 1) //PORTB口RB电平变化中断
{
RBIF = 0;
portbData = (PORTB & 0XF0);
if (RB4 == 0) // 有键按下
{

}
}
}

下面是PWM文件:

#include"sysAll.h"
#include <xc.h>
#include <plib.h>
void PWM_Init(void);
void PWM_setDutyCycle(uint DutyCycle);
void PWM_setPeriod(uchar newPeriod);
/******************************************************************************
**Code
******************************************************************************/
/** void PWM_Init(void)
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/
void PWM_Init(void)
{

TRISB3 = 0;
PWM_setPeriod(80);
PWM_setDutyCycle(40);
CCP1CONbits.CCP1M = 0X0C;
PSTR1CONbits.STRA = 1;
PPSUnLock();
RPOR6 = 14;//RP6引脚对应第14个功能,即PWM输出
TCLKCON = 0X12;
T4CONbits.T4CKPS = 0;
T4CONbits.TMR4ON = 1;
}
/** void PWM_setPeriod(uchar newPeriod)
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/


void PWM_setDutyCycle(uint DutyCycle)
{
uint newDutyCycle;
newDutyCycle = ((DutyCycle << 3) + (DutyCycle << 2));
CCPR1L = (newDutyCycle >> 2);
CCP1CONbits.DC1B = 0x00;
CCP1CONbits.DC1B |= newDutyCycle;
}

/** void PWM_setPeriod(uchar newPeriod)
*
*
* @param a param描述参数
* @return return void
* @see
* @note
*/
void PWM_setPeriod(uchar newPeriod)
{

uchar Period;
Period = newPeriod + newPeriod + newPeriod;
PR4 = (Period - 1);
}

 

sys.h文件

#ifndef _SYSALL_H_
#define _SYSALL_H_
#ifndef __18F26J50
#define __18F26J50
#endif
typedef unsigned int uint;
typedef unsigned char uchar;
#define USART_CONTS_MAX 32
#define CAPTCONTMAX 500

/**
* u16Union_t
* 方便不同的任务访问,特别适合既要比较又要存贮序列化的场合
*/

typedef union {
uint m_Uint;
uchar m_u8Array[2];
} u16Union_t;


void delayms(uint ms);
void USART1Send(char * data, uint length);
void PWM_Init(void);
void PWM_setDutyCycle(uint DutyCycle);
void PWM_setPeriod(uchar newPeriod);

void capture2Init(void);
void capture2Start(void);
void capture2Close(void);


#endif // _AS10F200_H_

 

推荐阅读