历史上的今天
今天是:2024年10月25日(星期五)
2019年10月25日 | PIC单片机PWM电机速度控制源码-实用C语言程序设计与典型实例
2019-10-25 来源:51hei
单片机源程序如下:
#include #include "16x2LCDDriver.h" unsigned char LCDBuffer_0[]={"STOP 00% DIR +"}; unsigned char LCDBuffer_1[]={"Get Spd 0000 RPM"}; struct TMR1COUNTER_STRUCT { unsigned char HighCounter; unsigned int LowCounter; unsigned char ChangeFlag; }; struct TMR1COUNTER_STRUCT MyTMR1,MyTMR3,GetTMR1,GetTMR3; void OSCillator_Initize(void) { OSCCON=0x70;//选择内部8MHz的主振荡器 OSCTUNE=0x40;//使能4xPLL--->Fosc=32MHz } void PIC_PortDir_Initize(void) { ADCON1=0x0F;//RA和RE端口全为数字IO口 TRISD=0x00;//RD端口置输出方向 TRISE=0x00;//RE端口置输出方向 TRISCbits.TRISC1=0; TRISCbits.TRISC2=0; TRISCbits.TRISC3=0; } void PIC_TMR0_Initize(void) { T0CONbits.TMR0ON=0;//TMR0停止工作 T0CONbits.T08BIT=0;//选择16位的定时/计数器 T0CONbits.T0CS=0;//选择内部CLKO时钟源作为定时 T0CONbits.PSA=0;//选择预分频器 T0CONbits.T0PS2=1;//预分频比为1:256 T0CONbits.T0PS1=1; T0CONbits.T0PS0=1; TMR0H=(65536-31250)/256;//先写高字节 TMR0L=(65536-31250)%256;//再写低字节 T0CONbits.TMR0ON=1;//开始定时工作 } void PIC_TMR1_Initize(void) { //此处TMR1的预分频比为1:1 T1CONbits.RD16=1;//允许一次性读写16位 T1CONbits.TMR1CS=1;//选择外部时钟源,TMR1用作外部计数 TMR1H=0;//TMR1数据寄存器清0 TMR1L=0; T1CONbits.TMR1ON=1;//允许TMR1开始工作 } void PIC_TMR3_Initize(void) { //此处TMR1的预分频比为1:8 T3CONbits.T3CKPS1=1; T3CONbits.T3CKPS0=1; T3CONbits.RD16=1;//允许一次性读写16位 T3CONbits.TMR3CS=0;//选择内部时钟源,TMR3用作内部计数 TMR3H=0;//TMR3数据寄存器清0 TMR3L=0; T3CONbits.TMR3ON=1;//允许TMR3开始工作 } void PIC_Interrupt_Initize(void) { INTCONbits.TMR0IF=0;//TMR0溢出标志位清0 INTCONbits.TMR0IE=1;//TMR0溢出中断允许 PIR1bits.TMR1IF=0;//TMR1溢出标志位清0 PIE1bits.TMR1IE=1;//TMR1溢出中断允许 IPR1bits.TMR1IP=0;//低优先级 PIR2bits.TMR3IF=0;//TMR1溢出标志位清0 PIE2bits.TMR3IE=1;//TMR1溢出中断允许 IPR2bits.TMR3IP=0;//低优先级 INTCONbits.INT0IF=0;//清INT0中断标志位 //INTCONbits.INT0IE=1;//INT0中断允许 INTCON2bits.RBPU=0;//允许内部弱上拉 INTCON2bits.INTEDG0=1;//上边沿触发中断 RCONbits.IPEN=1;//允许中断优先级位 INTCONbits.GIE=1;//CPU全局中断使能允许 INTCONbits.PEIE=1;//CPU第二梯队中断使能允许 } void PIC_CCPForPWM_Initize(void) { TRISCbits.TRISC1=0;//RC1置输出方向 TRISCbits.TRISC2=0;//RC2置输出方向 LATCbits.LATC1=0;//RC1引脚输出为0 LATCbits.LATC2=0;//RC2引脚输出为0 CCP1CON=0x0F;//CCP1设置为PWM模式 CCP2CON=0x0F;//CCP2设置为PWM模式 T2CON=0x03;//TMR2的预分频为1:16 T2CONbits.TMR2ON=1;//TMR2开始工作 PR2=249;//PWM周期为2000Hz,FOSC=32MHz CCPR1L=0;//PWM1的占空比为0 CCPR2L=0;//PWM2的占空比为0 } unsigned char CycleFlag; unsigned char FreqFlag; #define RUNSTOPKEY PORTBbits.RB3 #define PWMKEY PORTBbits.RB4 #define DIRKEY PORTBbits.RB5 unsigned char MotorRunStatus; unsigned char MotorDirection; unsigned char MotorPWMData; unsigned char RunStopKeyFlag; unsigned int RunStopKeyCounter; unsigned char DirKeyFlag; unsigned int DirKeyCounter; unsigned char PWMKeyFlag; unsigned int PWMKeyCounter; void SystemVariant_Initize(void) { MotorPWMData=0; } void Motor_Control(unsigned char Direction, unsigned char Speed) { switch(Direction) { case 0: CCPR1L=0; CCPR2L=0; CCPR1L=Speed; break; case 1: CCPR2L=0; CCPR1L=0; CCPR2L=Speed; break; } } //------------------------------------------------------------------- void PIC18F_High_isr(void);//高优先级中断函数声明 #pragma code high_vector_section=0x8 void high_vector (void) { _asm goto PIC18F_High_isr _endasm } void SystemInterruptISR(void);//低优先级中断函数声明 #pragma code low_vector=0x18//低中断优先级 void low_interrupt(void) { _asm goto SystemInterruptISR _endasm } #pragma code //------------------------------------------------------------------- void main(void) { unsigned long temp; unsigned char i; OSCillator_Initize();//CPU系统时钟初始化内部时钟源8MHz,经过4xPLL PIC_PortDir_Initize();//PIC单片机的使用到的I/O口方向初始化 PIC_TMR0_Initize();//PIC单片机的TMR0定时器初始化为内部定时方式 PIC_TMR1_Initize();//PIC单片机的TMR1定时器初始化为外部计数方式 PIC_TMR3_Initize(); PIC_CCPForPWM_Initize(); PIC_Interrupt_Initize(); initize_lcd(); while(1) { if(0==RUNSTOPKEY)//判断启动按键是否按下 { if(0==RunStopKeyFlag)//检测启动按键是否成功按下标志 { RunStopKeyCounter++;//软件计数器,用于按键去抖动 if(4000==RunStopKeyCounter)//按键去抖动延时到 { RunStopKeyCounter=0;//清软计数器为0 if(0==RUNSTOPKEY)//再判断启动按键是否真得按下 { RunStopKeyFlag=1;//置启动按键成功按下标志为1 if(0==MotorRunStatus)//如果电机是处理停止状态 {//则启动电机运转 MotorRunStatus=1;//同时置电机状态为1 LCDBuffer_0[0]='R';//LCD显示屏上显示"RUN" LCDBuffer_0[1]='U'; LCDBuffer_0[2]='N'; LCDBuffer_0[3]=' '; LCDBuffer_0[4]=' '; temp=MotorPWMData;//读取设置电机速度的变量 temp<<=1;//转换成占空比送到LCD上显示 temp/=5; LCDBuffer_0[5]=(temp/10)+0x30; LCDBuffer_0[6]=(temp%10)+0x30; LCDBuffer_0[7]='%'; LCDBuffer_0[8]=' '; LCDBuffer_0[9]='D'; LCDBuffer_0[10]='I'; LCDBuffer_0[11]='R'; LCDBuffer_0[12]=' '; if(0==MotorDirection)//根据电机运转的方向 {//来设置电机是正转还是反转,并在LCD上显示
史海拾趣
|
教你读懂MOSFET datasheet说明书所有功率MOS制造厂商都会提供每种型号产品的详细说明书。 说明书用来说明各种产品的性能。这对于在不同厂商之间选择相同规格的器件很有用。在一些情况下,不同厂商所提供的参数所依据的条件可能有微妙的区别,尤其在 ...… 查看全部问答> |
|
希望利用网卡驱动程序将IP数据报的首部与数据分离,然后单独加密数据,网卡驱动程序可以做到吗?要重新编写网卡驱动程序是吧。期待回答,谢谢!… 查看全部问答> |
|
根据实际要求需要中频输出,就是接收到数据后在解调前把变换过的数据引出来另作他用 搜索了相关的数据手册 cc1000提供 接收数据后经过LNA 混频 将得到的IF模拟输出 但是不知道其频道切换时间是多少,要考虑一下 还有TRF6900提供一级IF参考输入输 ...… 查看全部问答> |
|
各位大侠,小弟有个问题请教: 请问:将用户开发的程序存储到SPI FLASH后供其他芯片调用,有没有什么措施《防止FLASH中的数据被导出》,导出数据有时能够直接用于其他FLASH中; 另外,是否有自带加密功能的SPI FLASH芯片呢,如果有,请推荐下型号 ...… 查看全部问答> |
|
WCE Application程序可不可以使用MFC类库?如果可以,要怎样使用?小弟直接包含MFC的头文件,结果当在程序中使用了new时,出现编译错误: uafxwced.lib(afxmem.obj) : error LNK2005: \"void * __cdecl operator new(unsigned int)\" (??2@YAPAXI@ ...… 查看全部问答> |
|
我西门是个没什么水平的人,这次的原理图是我画的,比较匆忙,也比较粗糙.不妥之处,希望高手给予指点和帮助.不胜感激! [ 本帖最后由 西门 于 2010-9-7 17:40 编辑 ]… 查看全部问答> |




