PIC18F占空比计算
- 格式:xls
- 大小:34.00 KB
- 文档页数:2
科研训练题目:单片机的红外通信系统设计指导教师:学生姓名:班级学号:评语和成绩:摘要:本文索要介绍的内容就是如何利用单片机,结合红外线器件设计构建出一套简易的红外通信系统,以实现在中短距离内的红外无线通信的功能。
与一般红外遥控器不同的是本文通过单片机的编、解码程序来实现红外信号的发收,从而实现红外遥控通信功能。
此通信系统经过一定的拓展,完全可以实现通信和各种红外遥控器的功能。
关键字:单片机;红外通信;发射;接收;遥控;接口Abstract:This paper introduced the content of that how to use for SCM, combined with the infrared device design to construct a simple infrared communication system, in order to realize the infrared wireless communication in short distance within the function. Unlike the general infrared remote control is based on single chip encoding, decoding process to achieve the infrared signal sending and receiving, so as to realize the infrared remote control function. This communication system after a certain development, can achieve communication and various kinds of infrared remote control function.Keywords: single chip; infrared communication; emission; reception; remote control; interface1红外线通信原理红外数据通信指的是两台设备之间通过红外线进行无线数据传输的一种数据传输方式,一般采用红外波段内的近红外线,波长在0.75μm至25μm之间。
什么是占空比占空比(Duty Cycle)在电信领域中意思:在一串理想的脉冲序列中(如方波),正脉冲的持续时间与脉冲总周期的比值。
例如:脉冲宽度1μs,信号周期4μs的脉冲序列占空比为0.25。
在一段连续工作时间内脉冲占用的时间与总时间的比值。
在CVSD调制(continuously variable slope delta modulation)中,比特“1”的平均比例(未完成)。
在周期型的现象中,现象发生的时间与总时间的比。
负载周期在中文成语中有句话可以形容:「一天捕渔,三天晒网」,则负载周期为0.25。
占空比是高电平所占周期时间与整个周期时间的比值。
占空比越大,高电平持续的时间越长,电路的开通时间就越长PWM值增加则占空比减少!!!!!!!(请先看下面关于PWM的定义)PWM值增加应该是周期变大,那么占空比就减小了(此为个人见解如有不同见解请发邮箱1250712643@)占空比的图例什么是占空比(另一种解释)占空比是指高电平在一个周期之内所占的时间比率。
方波的占空比为50%,占空比为0.1,说明正电平所占时间为0.1个周期。
正脉冲的持续时间与脉冲总周期的比值。
例如:正脉冲宽度1μs,信号周期10μs的脉冲序列占空比为0.1。
什么是PWM1.脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写,简称脉宽调制。
它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量,通信,功率控制与变换等许多领域。
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。
通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。
电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。
通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。
标准文案大全本科毕业设计(论文)题目单片机控制的直流斩波器院系专业名称电子信息工程年级班级学生姓名指导教师年月日摘要传统开关电源是模数结合的硬件为主的控制方式,其控制精度、响应速度等都由电路拓扑结构和器件本身的参数决定,很难进一步提升其性能。
随着微处理器处理技术的日趋成熟,开关电源的软硬件结合的控制技术得到了广泛的关注,它呈现出纯硬件控制方式无法比拟的优点。
本论文以单片机为控制核心对开关电源进行了可编程控制的设计。
首先介绍了开关电源数控技术的研究现状及趋势;对整个系统的硬件电路进行了各模块的设计及对应器件的选型;在此基础上,对软件部分实现过程进行了详细阐述。
【关键词】单片机,开关电源AbstractConventional switching power supply is combined with hardware-based module control mode, the control accuracy, response speed by the circuit topology and device parameters of the decision itself, it is difficult to further improve its performance. With the microprocessor processing technology matures, switching power supply control software and hardware combination technology has been widespread concern, it presents a pure hardware control mode can not match advantage.In this thesis, the core of the microcontroller for the control of switching power supply for the programmable control of the attempt. First introduced the technique of switching power supply CNC status and trends; on the whole system has briefly introduces the hardware design and partial implementation of the software process described in detail.Key words: microcontroller, switching power supply目录目录 (3)第一章前言 (5)1.选题目的和意义 (5)2.国内外综述 (5)第二章系统硬件设计 (1)2.1系统原理 (1)2.2硬件的选取 (2)2.3半桥输出的PWM波产生电路 (3)2.4A/D采样及调理电路 (4)2.41电压采样电路 (4)2.42 电流采样调理电路 (5)2.5矩阵键盘电路 (5)2.6液晶LCD显示电路 (7)2.61 液晶1602显示器介绍 (7)2.62本系统中1602的应用 (8)第三章系统软件设计 (1)3.1软件设计总体思路 (2)3.2系统主程序模块 (2)3.21 始初化模块 (3)3.22 PWM波发生模块 (3)3.23 A/D转换模块 (7)3.24 PID算法处理模块 (11)3.25 LCD液晶显示模块 (13)3.26 按键处理模块 (14)3.3中断服务程序模块 (15)3.31 中断程序原理及框图 (15)3.32 数字滤波算法 (16)第四章结论 (18)致谢 (20)参考文献 (21)附录 (23)目录?前言1.选题目的和意义直流斩波电路(DC Chopper)的功能是将直流电变为另一固定电压或可调电压的直流电。
永磁体占空比计算公式永磁体占空比计算公式是在永磁体应用领域中的一个重要概念。
永磁体占空比是指永磁体在一个周期内的工作时间占总时间的比例,通常用来描述永磁体在电机、发电机等设备中的工作性能。
在永磁体应用中,占空比的大小会直接影响到设备的性能和效率。
因此,了解永磁体占空比的计算公式对于永磁体应用领域的工程师和研究人员来说是非常重要的。
永磁体占空比的计算公式可以根据具体的应用场景和设备特性来进行推导和计算。
在电机和发电机中,通常会用到两种不同的占空比计算公式,分别是基于电压波形和电流波形的计算公式。
下面将分别介绍这两种计算公式的推导和应用。
基于电压波形的永磁体占空比计算公式可以通过以下步骤来推导。
首先,我们需要了解永磁体在电机或发电机中的工作原理。
在正常工作状态下,永磁体会受到外部电压的作用而产生磁场,从而驱动设备进行工作。
在一个周期内,永磁体的工作时间可以通过电压波形的周期来表示。
因此,永磁体的占空比可以通过以下公式来计算:占空比 = 工作时间 / 周期时间。
其中,工作时间可以通过电压波形的积分来计算,周期时间则是电压波形的周期。
通过这个公式,我们可以得到永磁体在一个周期内的占空比,从而评估设备的工作性能。
另一种常用的永磁体占空比计算公式是基于电流波形的。
在电机和发电机中,永磁体的工作状态通常会受到电流的影响。
因此,我们可以通过电流波形来计算永磁体的占空比。
具体的计算步骤如下:首先,我们需要获取电流波形的周期时间和工作时间,然后通过以下公式来计算永磁体的占空比:占空比 = 工作时间 / 周期时间。
通过这个公式,我们可以得到永磁体在一个周期内的工作时间占总时间的比例,从而评估设备的工作性能。
在实际的永磁体应用中,占空比的大小会直接影响到设备的性能和效率。
因此,了解永磁体占空比的计算公式对于永磁体应用领域的工程师和研究人员来说是非常重要的。
通过计算占空比,我们可以评估设备的工作性能,并且优化设备的设计和控制策略,从而提高设备的效率和性能。
PIC18 单片机学习(程序实例)说明:18F基本模块初始化程序均在内,且测试通过,主程序可以调用各个程序!编译器使用PICC18//程序主要用于18F单片机学习#include <pic18.h> //18系列单片机头文件//-------------函数定义--------------void delay(unsigned int rr);void timer1(void);void SPI_Iint(void); //串行SPI输出设置函数void display(void);void i2cint(void); //i2c总线初始化程序void c64R(void); //i2c接口的EEPROM存储器(读程序)void c64W(void); //写程序void Start(void); //起始位发送函数void Stop(void); //停止位发送函数void WriteWait(void); //等待函数void Senddata(unsigned char data); //数据发送函数void Restart(void); //重复启动函数void Datain(void); //数据读入void Uartint(void); //通用同步/异步收发器初始化程序void Udatas(unsigned char dad); //UART数据发送void Uartrs(void); //串口接收数据发送函数void ADint(void); //AD模块初始化void shuchai(void);//-----------数据寄存器定义----------const unsigned char table[10]={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6}; //显示段码unsigned char buf[5]; //显示缓存unsigned char receive[10]; //定义接收缓存unsigned char dd; //定时器0,中断计数寄存器unsigned char save;unsigned char conet;unsigned char *Counter; //接收数据指针unsigned char DADh; //AD缓存,unsigned char DADl;unsigned int Dat;unsigned int Dat1; //保存上次的AD转换值,用于比volatile bit DADflage; //AD转换标志volatile bit I2Cerror; //I2C错误标志volatile bit Uartsend; //异步串口数据发送允许union //联合体用来对C64的地址进行操作!{unsigned char dizhi[2];unsigned int Adress;}add;#define AddLow add.dizhi[0]#define AddHigh add.dizhi[1]#define ADDss add.Adress//***********************************//初始化//***********************************void PICint(){SWDTEN=1; //禁止看门狗,18F看门狗是可以用软件控制开启的!INTCON=0;ADCON1=0x07; //AD端口全部始能为数字IO口TRISB7=0; //设置为输出端口RB7=0;PIE1=0;PIE2=0;PIE3=0;buf[0]=0;buf[1]=0;buf[2]=0;buf[3]=0;//CMCON=0x07; //关闭比较器,18F2680没有比较器}//***********************************//高优先级中断函数//***********************************void interrupt HI_ISR(){if(TMR0IF&TMR0IE) //确认是定时器0中断{dd++;TMR0IF=0;TMR0H=0xd8; //10ms定时常数TMR0L=0xef;if(dd==100){dd=0;buf[0]++;if(buf[0]==10){buf[0]=0;buf[1]++;if(buf[1]==10){buf[1]=0;buf[2]++;if(buf[2]==10){buf[2]=0;buf[3]++;if(buf[3]==10){buf[3]=0;}}}}}}if(ADIF) //判断是否是AD转换中断{ADIF=0; //清0DADh=ADRESH;DADl=ADRESL;Dat=256*DADh+DADl;if(((Dat-Dat1)==1)||((Dat1-Dat)==1)){Dat=Dat1;}DADflage=1;}}//***********************************//低优先级中断函数//***********************************void interrupt low_priority LOW_ISR(){if(RCIF&RCIE) //如果是串口接收中断的话,则进入中断处理{RCIF=0; //清中断标志*Counter=RCREG;//读取数据到数组Counter++;if((Counter-&receive[0])==10){Counter=&receive[0];Uartsend=1;}}}//***********************************//定时器0初始化子程序//***********************************void timer1(){IPEN=1; //打开高低优先级T0CON=0x09; //把定时器0设定为16位定时器,内部时钟触发,不使用分频器TMR0IE=1; //允许定时器0溢出中断TMR0IF=0; //清除中断标志TMR0IP=1; //设定定时器0中断为高优先级TMR0H=0xD8; //定时常数TMR0L=0xef;GIE=1;PEIE=1;TMR0ON=1;}//***********************************//AD转换初始化函数//***********************************void ADint() //使用于18F2680!{ADCON0=0x01; //AD转换速率为Fosc/4,并使能AD转换模块ADCON1=0x0e; //选择为右对齐模式,并且使能AD0为模拟通道ADCON2=0x91;TRISA=1; //RA0为输入模式ADIF=0;ADIE=1; //中断使能IPEN=1; //使能高低中断优先级ADIP=1; //AD转换设置为高优先级中断GIE=1; //开总中断以及外部中断PEIE=1;DADflage=0;}//***********************************//I2C初始化函数//***********************************void i2cint(){SSPCON1=0x08; //允许串口工作,I2C主控方式,时钟=Fosc/[4*(SSPADD+1)] RC4=1; //设置为输入RC3=1;SSPADD=7; //时钟频率约为0.125MSSPSTAT=0x80; //关闭标准速度方式SSPCON2=0;SSPEN=1; //使能串口(SSP模块)I2Cerror=0;}//***********************************//SPI初始化程序//***********************************void SPI_Iint(){TRISC5=0; //SDO引脚TRISC4=1; //SDI引脚TRISC3=0; //SCK,串行时钟输出引脚TRISA5=0; //RA5为从动SS端SSPCON1=0x30; //使能串口,高电平为空闲状态,并且发送频率为fose/4,主控方式; SSPSTAT=0xc0; //时钟下降沿发送数据!SSPIF=0;conet=0;}//***********************************//通用同步/异步收发器(UART)初始化//***********************************void Uartint(){TXSTA=0x04; //设置为高速异步,方式RCSTA=0x80; //使能UARTTRISC6=0; //设置为输入,对外部呈现高阻态TRISC7=1;SPBRG=25; //设置波特率为9600//波特率计算公式//1.同步方式:波特率=Fosc/[4(X+1)]//2.异步方式:BRGH=0:波特率=Fosc/[64(x+1)]// BRGH=1:波特率=Fosc/[16(x+1)]IPEN=1; //开中断优先级RCIP=0; //串口接收使能为低优先级RCIE=1; //串口接收中断使能RCIF=0;TXIE=0; //禁止发送中断GIE=1; //开总中断和外围中断PEIE=1;TXEN=1; //使能串口发送CREN=1; //使能串口接收,注意18F是CREN而不是RCEN,编译器都认为是正确的但是RCEN不管用! Counter=&receive[0];//把数组的首地址给指针Uartsend=0;}//***********************************//AD转换函数//***********************************void ADchange(){ADCON0=ADCON0|0x02; //启动AD转换if(DADflage) //如果AD转换完成,这里采用{DADflage=0;shuchai();display();}}//***********************************//AD 数据拆分//***********************************void shuchai(){unsigned int i;Dat1=Dat; //保存这次的计数值i=Dat;buf[3]=i/1000; //取出千位i=i%1000; //取出百位数buf[2]=i/100; //取出百位数i=i%100; //取出十位数buf[1]=i/10;i=i%10;buf[0]=i;}//***********************************//Uart receive data send//***********************************void Uartrs(){if(Uartsend){unsigned char i;Uartsend=0;for(i=0;i<10;i++){Udatas(*Counter);Counter++;}Counter=&receive[0]; //重新初始化}}//***********************************//Uart 数据发送子程序//***********************************void Udatas(unsigned char dad){TXREG=dad;while(1){if(TXIF==1) break; //等待数据写入}delay(80);}//***********************************//I2C写子程序//***********************************void c64W(){Start();if(I2Cerror==1){I2Cerror=0;return; //返回防止死循环}Senddata(0xa0); //发送寻址地址,以及写操作地址!if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x00); //发送高位地址if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x40); //发送地址低字节if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x55); //发送数据if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Stop();}//***********************************//I2C读数据程序//***********************************void c64R(){Start();if(I2Cerror==1){I2Cerror=0;return; //返回防止死循环}Senddata(0xa0); //发送寻址地址,以及写操作地址!if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x00); //发送高位地址if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x40); //发送地址低字节if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Restart(); //发送重新起始位Senddata(0xa1); //发送读命令if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Datain();Stop();if(save==0x55){RB7=1;}conet++;}//***********************************//I2C重复启动//***********************************void Restart(){RSEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//***********************************//I2C数据写等待//***********************************void WriteWait(){while(1){Start(); //在数据写入时间,如果在给器件发送数据不会有响应Senddata(0xa0);Stop();if(I2Cerror==0) break; //等待数据写入,=0则有应答位产生}}//***********************************//I2C起始位发送函数//***********************************void Start(){unsigned char i=0;SEN=1; //起始位发送while(1){i++;if(SSPIF==1) break;if(i==200) //防止死循环{i=0;I2Cerror=1;break;}}SSPIF=0;}//***********************************//I2C停止位发送//***********************************void Stop(){PEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//***********************************//I2C数据发送函数//***********************************void Senddata(unsigned char data){unsigned char i;SSPBUF=data; //发送数据while(1){if(SSPIF==1) break;}SSPIF=0;for(i=0;i<10;i++){}if(ACKSTAT) //如果没有发出应答信号{I2Cerror=1;}else //如果发出应答信号{I2Cerror=0;}}//***********************************//I2C 数据读入函数//***********************************void Datain(){RCEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;save=SSPBUF; //读数ACKDT=1; //发送非应答位ACKEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//***********************************//164显示程序//***********************************void display() //164显示程序,用SPI端口发送数据{unsigned char i;unsigned char y,t; //传输完四个字节for(i=0;i<4;i++){y=buf[i];t=table[y];SSPBUF=t;while(1){if(SSPIF) break;}SSPIF=0;}}//***********************************//延时函数//*********************************** void delay(unsigned int rr) //延时函数{unsigned int asd;for(asd=0;asd<rr;asd++){}}//***********************************//主函数//*********************************** void main(){PICint(); //初始化函数//Uartint(); //异步串行口初始化//SPI_Iint();//ADint(); //AD模块初始化//timer1();//display();//i2cint(); //I2C初始化//c64W(); //往C64里写一次数据//WriteWait();//c64R(); //读C64里while(1){//CLRWDT();//delay(20000);CLRWDT();RB7=1;CLRWDT();SLEEP(); //等待看门狗复位RB7=0;delay(20000);CLRWDT();}}PIC18 单片机学习(程序实例)说明:18F基本模块初始化程序均在内,且测试通过,主程序可以调用各个程序!编译器使用PICC18//程序主要用于18F单片机学习#include <pic18.h> //18系列单片机头文件//-------------函数定义--------------void delay(unsigned int rr);void timer1(void);void SPI_Iint(void); //串行SPI输出设置函数void display(void);void i2cint(void); //i2c总线初始化程序void c64R(void); //i2c接口的EEPROM存储器(读程序)void c64W(void); //写程序void Start(void); //起始位发送函数void Stop(void); //停止位发送函数void WriteWait(void); //等待函数void Senddata(unsigned char data); //数据发送函数void Restart(void); //重复启动函数void Datain(void); //数据读入void Uartint(void); //通用同步/异步收发器初始化程序void Udatas(unsigned char dad); //UART数据发送void Uartrs(void); //串口接收数据发送函数void ADint(void); //AD模块初始化void shuchai(void);//-----------数据寄存器定义----------const unsigned char table[10]={0xee,0x82,0xdc,0xd6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6}; //显示段码unsigned char buf[5]; //显示缓存unsigned char receive[10]; //定义接收缓存unsigned char dd; //定时器0,中断计数寄存器unsigned char save;unsigned char conet;unsigned char *Counter; //接收数据指针unsigned char DADh; //AD缓存,unsigned char DADl;unsigned int Dat;unsigned int Dat1; //保存上次的AD转换值,用于比volatile bit DADflage; //AD转换标志volatile bit I2Cerror; //I2C错误标志volatile bit Uartsend; //异步串口数据发送允许union //联合体用来对C64的地址进行操作!{unsigned char dizhi[2];unsigned int Adress;}add;#define AddLow add.dizhi[0]#define AddHigh add.dizhi[1]#define ADDss add.Adress//***********************************//初始化//***********************************void PICint(){SWDTEN=1; //禁止看门狗,18F看门狗是可以用软件控制开启的!INTCON=0;ADCON1=0x07; //AD端口全部始能为数字IO口TRISB7=0; //设置为输出端口RB7=0;PIE1=0;PIE2=0;PIE3=0;buf[0]=0;buf[1]=0;buf[2]=0;buf[3]=0;//CMCON=0x07; //关闭比较器,18F2680没有比较器}//***********************************//高优先级中断函数//***********************************void interrupt HI_ISR(){if(TMR0IF&TMR0IE) //确认是定时器0中断{dd++;TMR0IF=0;TMR0H=0xd8; //10ms定时常数TMR0L=0xef;if(dd==100){dd=0;buf[0]++;if(buf[0]==10){buf[0]=0;buf[1]++;if(buf[1]==10){buf[1]=0;buf[2]++;if(buf[2]==10){buf[2]=0;buf[3]++;if(buf[3]==10){buf[3]=0;}}}}}}if(ADIF) //判断是否是AD转换中断{ADIF=0; //清0DADh=ADRESH;DADl=ADRESL;Dat=256*DADh+DADl;if(((Dat-Dat1)==1)||((Dat1-Dat)==1)){Dat=Dat1;}DADflage=1;}}//***********************************//低优先级中断函数//***********************************void interrupt low_priority LOW_ISR(){if(RCIF&RCIE) //如果是串口接收中断的话,则进入中断处理{RCIF=0; //清中断标志*Counter=RCREG;//读取数据到数组Counter++;if((Counter-&receive[0])==10){Counter=&receive[0];Uartsend=1;}}}//***********************************//定时器0初始化子程序//***********************************void timer1(){IPEN=1; //打开高低优先级T0CON=0x09; //把定时器0设定为16位定时器,内部时钟触发,不使用分频器TMR0IE=1; //允许定时器0溢出中断TMR0IF=0; //清除中断标志TMR0IP=1; //设定定时器0中断为高优先级TMR0H=0xD8; //定时常数TMR0L=0xef;GIE=1;PEIE=1;TMR0ON=1;}//***********************************//AD转换初始化函数//***********************************void ADint() //使用于18F2680!{ADCON0=0x01; //AD转换速率为Fosc/4,并使能AD转换模块ADCON1=0x0e; //选择为右对齐模式,并且使能AD0为模拟通道ADCON2=0x91;TRISA=1; //RA0为输入模式ADIF=0;ADIE=1; //中断使能IPEN=1; //使能高低中断优先级ADIP=1; //AD转换设置为高优先级中断GIE=1; //开总中断以及外部中断PEIE=1;DADflage=0;}//***********************************//I2C初始化函数//***********************************void i2cint(){SSPCON1=0x08; //允许串口工作,I2C主控方式,时钟=Fosc/[4*(SSPADD+1)] RC4=1; //设置为输入RC3=1;SSPADD=7; //时钟频率约为0.125MSSPSTAT=0x80; //关闭标准速度方式SSPCON2=0;SSPEN=1; //使能串口(SSP模块)I2Cerror=0;}//***********************************//SPI初始化程序//***********************************void SPI_Iint(){TRISC5=0; //SDO引脚TRISC4=1; //SDI引脚TRISC3=0; //SCK,串行时钟输出引脚TRISA5=0; //RA5为从动SS端SSPCON1=0x30; //使能串口,高电平为空闲状态,并且发送频率为fose/4,主控方式; SSPSTAT=0xc0; //时钟下降沿发送数据!SSPIF=0;conet=0;}//***********************************//通用同步/异步收发器(UART)初始化//***********************************void Uartint(){TXSTA=0x04; //设置为高速异步,方式RCSTA=0x80; //使能UARTTRISC6=0; //设置为输入,对外部呈现高阻态TRISC7=1;SPBRG=25; //设置波特率为9600//波特率计算公式//1.同步方式:波特率=Fosc/[4(X+1)]//2.异步方式:BRGH=0:波特率=Fosc/[64(x+1)]// BRGH=1:波特率=Fosc/[16(x+1)]IPEN=1; //开中断优先级RCIP=0; //串口接收使能为低优先级RCIE=1; //串口接收中断使能RCIF=0;TXIE=0; //禁止发送中断GIE=1; //开总中断和外围中断PEIE=1;TXEN=1; //使能串口发送CREN=1; //使能串口接收,注意18F是CREN而不是RCEN,编译器都认为是正确的但是RCEN不管用! Counter=&receive[0];//把数组的首地址给指针Uartsend=0;}//***********************************//AD转换函数//***********************************void ADchange(){ADCON0=ADCON0|0x02; //启动AD转换if(DADflage) //如果AD转换完成,这里采用{DADflage=0;shuchai();display();}}//***********************************//AD 数据拆分//***********************************void shuchai(){unsigned int i;Dat1=Dat; //保存这次的计数值i=Dat;buf[3]=i/1000; //取出千位i=i%1000; //取出百位数buf[2]=i/100; //取出百位数i=i%100; //取出十位数buf[1]=i/10;i=i%10;buf[0]=i;}//***********************************//Uart receive data send//***********************************void Uartrs(){if(Uartsend){unsigned char i;Uartsend=0;for(i=0;i<10;i++){Udatas(*Counter);Counter++;}Counter=&receive[0]; //重新初始化}}//***********************************//Uart 数据发送子程序//***********************************void Udatas(unsigned char dad){TXREG=dad;while(1){if(TXIF==1) break; //等待数据写入}delay(80);}//***********************************//I2C写子程序//***********************************void c64W(){Start();if(I2Cerror==1){I2Cerror=0;return; //返回防止死循环}Senddata(0xa0); //发送寻址地址,以及写操作地址!if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x00); //发送高位地址if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x40); //发送地址低字节if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x55); //发送数据if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Stop();}//***********************************//I2C读数据程序//***********************************void c64R(){Start();if(I2Cerror==1){I2Cerror=0;return; //返回防止死循环}Senddata(0xa0); //发送寻址地址,以及写操作地址!if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x00); //发送高位地址if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Senddata(0x40); //发送地址低字节if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Restart(); //发送重新起始位Senddata(0xa1); //发送读命令if(I2Cerror==1){I2Cerror=0;Stop(); //错误处理return; //返回防止死循环}Datain();Stop();if(save==0x55){RB7=1;}conet++;}//*********************************** //I2C重复启动//*********************************** void Restart(){RSEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//*********************************** //I2C数据写等待//*********************************** void WriteWait(){while(1){Start(); //在数据写入时间,如果在给器件发送数据不会有响应Senddata(0xa0);Stop();if(I2Cerror==0) break; //等待数据写入,=0则有应答位产生}}//***********************************//I2C起始位发送函数//***********************************void Start(){unsigned char i=0;SEN=1; //起始位发送while(1){i++;if(SSPIF==1) break;if(i==200) //防止死循环{i=0;I2Cerror=1;break;}}SSPIF=0;}//***********************************//I2C停止位发送//***********************************void Stop(){PEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//***********************************//I2C数据发送函数//***********************************void Senddata(unsigned char data){unsigned char i;SSPBUF=data; //发送数据while(1){if(SSPIF==1) break;}SSPIF=0;for(i=0;i<10;i++){}if(ACKSTAT) //如果没有发出应答信号{I2Cerror=1;}else //如果发出应答信号{I2Cerror=0;}}//***********************************//I2C 数据读入函数//***********************************void Datain(){RCEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;save=SSPBUF; //读数ACKDT=1; //发送非应答位ACKEN=1;while(1){if(SSPIF==1) break;}SSPIF=0;}//***********************************//164显示程序//***********************************void display() //164显示程序,用SPI端口发送数据{unsigned char i;unsigned char y,t; //传输完四个字节for(i=0;i<4;i++){y=buf[i];t=table[y];SSPBUF=t;while(1){if(SSPIF) break;}SSPIF=0;}}//***********************************//延时函数//*********************************** void delay(unsigned int rr) //延时函数{unsigned int asd;for(asd=0;asd<rr;asd++){}}//***********************************//主函数//*********************************** void main(){PICint(); //初始化函数//Uartint(); //异步串行口初始化//SPI_Iint();//ADint(); //AD模块初始化//timer1();//display();//i2cint(); //I2C初始化//c64W(); //往C64里写一次数据//WriteWait();//c64R(); //读C64里while(1){//CLRWDT();//delay(20000);CLRWDT();CLRWDT();SLEEP(); //等待看门狗复位RB7=0;delay(20000);CLRWDT();}}关于c语言流水灯程序悬赏分:20|解决时间:2010-4-13 17:04|提问者:chenli6522002流水灯怎么在下面代码中不能点亮,出现什么问题了?#include "reg51.h"char led[]={0x01,0x02,0x04,0x08};char led1[]={0x01,0x04,0x02,0x08,0x08,0x02,0x04,0x01};char led2[]={0x08,0x04,0x02,0x01};void delay(unsigned int time){ unsigned int j;for(;time>0;time++)for(j=0;j<125;j++);}void main(){char i;while(1){if(P0==0x0e)while(1){for(i=0;i<=3;i++){P2=led[i];delay(200);}if(P0==0x0d||P0==0x0d)break;}else if(P0==0x0d)while(1)for(i=0;i<=3;i++){P2=led1[i];delay(200);}if(P0==0x0b||P0==0x0e) break;}else if(P0==0x0b)while(1){for(i=0;i<=3;i++){P2=led2[i];delay(200);}if(P0==0x0e||P0==0x0d)break;}else P2=0;}}最佳答案如果是流水灯你使用一下程序会更好简单实现的功能是P1 P3口的流水灯循环闪动你可以参照这个写..使用位控制#include "reg51.h"void main(){unsigned int i=10;P1=0xfe;while(1){while(--i){;}P1=(P1<<1) | 0x01;if(P1==0xff) P3 = 0x7f;while(P1==0xff){while(--i){;}P3=(P3>>1) | 0x80;{P1=0xfe;P3=0xff;}}}}音响程序#define uchar unsigned char //定义一下方便使用#define uint unsigned int#define ulong unsigned long#include <reg52.h> //包括一个52标准内核的头文件char code dx516[3] _at_ 0x003b;//这是为了仿真设置的sbit BEEP=P1^7; //喇叭输出脚sbit P10=P1^0;sbit K1= P3^2;sbit K2= P3^5;sbit K3= P2^4;sbit K4= P2^5;uchar th0_f; //在中断中装载的T0的值高8位uchar tl0_f; //在中断中装载的T0的值低8位//T0的值,及输出频率对照表uchar code freq[36*2]={0xA9,0xEF,//00220HZ ,1 //00x93,0xF0,//00233HZ ,1#0x73,0xF1,//00247HZ ,20x49,0xF2,//00262HZ ,2#0x07,0xF3,//00277HZ ,30xC8,0xF3,//00294HZ ,40x73,0xF4,//00311HZ ,4#0x1E,0xF5,//00330HZ ,50xB6,0xF5,//00349HZ ,5#0x4C,0xF6,//00370HZ ,60xD7,0xF6,//00392HZ ,6#0x5A,0xF7,//00415HZ ,70xD8,0xF7,//00440HZ 1 //120x4D,0xF8,//00466HZ 1# //130xBD,0xF8,//00494HZ 2 //140x24,0xF9,//00523HZ 2# //150x87,0xF9,//00554HZ 3 //160xE4,0xF9,//00587HZ 4 //170x3D,0xFA,//00622HZ 4# //180x90,0xFA,//00659HZ 5 //190xDE,0xFA,//00698HZ 5# //200x29,0xFB,//00740HZ 6 //210x6F,0xFB,//00784HZ 6# //220xB1,0xFB,//00831HZ 7 //230xEF,0xFB,//00880HZ `10x2A,0xFC,//00932HZ `1#0x62,0xFC,//00988HZ `20x95,0xFC,//01046HZ `2#0xC7,0xFC,//01109HZ `30xF6,0xFC,//01175HZ `40x22,0xFD,//01244HZ `4#0x4B,0xFD,//01318HZ `50x73,0xFD,//01397HZ `5#0x98,0xFD,//01480HZ `60xBB,0xFD,//01568HZ `6#0xDC,0xFD,//01661HZ `7 //35};//定时中断0,用于产生唱歌频率timer0() interrupt 1{TL0=tl0_f;TH0=th0_f; //调入预定时值BEEP=~BEEP; //取反音乐输出IO}//******************************//音乐符号串解释函数//入口:要解释的音乐符号串,输出的音调串,输出的时长串changedata(uchar *song,uchar *diao,uchar *jie){uchar i,i1,j;char gaodi; //高低+/-12音阶uchar banyin;//有没有半个升音阶uchar yinchang;//音长uchar code jie7[8]={0,12,14,16,17,19,21,23}; //C调的7个值*diao=*song;{gaodi=0; //高低=0banyin=0;//半音=0yinchang=4;//音长1拍if((*(song+i)=='|') || (*(song+i)==' ')) i++; //拍子间隔和一个空格过滤switch(*(song+i)){case ',': gaodi=-12;i++;//低音break;case '`': gaodi=12;i++; //高音break;}if(*(song+i)==0) //遇到0结束{*(diao+i1)=0; //加入结束标志0*(jie+i1)=0;return;}j=*(song+i)-0x30; i++; //取出基准音j=jie7[j]+gaodi; //加上高低音yinc: switch(*(song+i)){case '#': //有半音j加一个音阶i++;j++;goto yinc;case '-': //有一个音节加长yinchang+=4;i++;goto yinc;case '_': //有一个音节缩短yinchang/=2;i++;goto yinc;case '.': //有一个加半拍yinchang=yinchang+yinchang/2;i++;goto yinc;}*(diao+i1)=j; //记录音符*(jie+i1)=yinchang; //记录音长i1++;}}//******************************************//奏乐函数//入口:要演奏的音乐符号串void play(uchar *songdata){uchar i,c,j=0;uint n;uchar xdata diaodata[112]; //音调缓冲uchar xdata jiedata[112]; //音长缓冲changedata(songdata,diaodata,jiedata); //解释音乐符号串TR0=1;for(i=0;diaodata[i]!=0;i++) //逐个符号演奏{tl0_f=freq[diaodata[i]*2]; //取出对应的定时值送给T0th0_f=freq[diaodata[i]*2+1];for(c=0;c<jiedata[i];c++) //按照音长延时{for(n=0;n<32000;n++);if((!K1)||(!K2)||(!K3)||(!K4))//发现按键,立即退出播放{TR0=0;return;}}TR0=0;for(n=0;n<500;n++); //音符间延时TR0=1;}TR0=0;}//仙剑uchar code xianjian[]={"|3_3_3_2_3-|2_3_2_2_,6,6_,7_|12_1_,7,6_,5_|,6---|" "3_3_3_2_3.6_|5_6_5_5_22_3_|45_4_32_1_|3.--3_|" "67_6_55_3_|5--3_5_|26_5_32_3_|3---|""26_6_6-|16_6_66_7_|`17_6_76_7_|3.--3_|""67_6_55_3_|5--3_5_|67_6_76_7_|3---|""26_6_6-|16_6_66_7_|`17_6_7.5_|6---|"};uchar code song3[]={"5-5_3_2_1_|3---|6-6_4_2_1_"",7--,5_|1.3_5.1_|,7.3_5 5_|""6.7_`1.6_|6_5_5-3_2_|1.1_13_2_|""1.1_12_3_|2.1_,62_3_|2-- ,5_|""1.3_5.1_|,7.3_55_|6.7_`1.6_|""6_5_5-3_2_|1.1_13_2_|1.1_12_3_""2.,6_,71_2_|1--"};//世上只有妈妈好uchar code mamahao[]={"6.5_35|`16_5_6-|35_6_53_2_|1_,6_5_3_2-|""2.3_55_6_|321-|5.3_2_1_,6_1_|,5--"};//三个按键选择三首不同的音乐播放,一个键停止播放void main(void) // 主程序{TMOD = 0x01; //使用定时器0的16位工作模式TR0 = 0;ET0 = 1; //定时器0中断EA = 1; //打开总中断while(1){if(!K1){while(!K1);play(xianjian); //播放音乐}if(!K2){while(!K2);play(song3); //播放音乐}if(!K3){while(!K3);play(mamahao); //播放音乐}}}延时程序(包括asm和C程序,都是我在学单片机的过程中用到的),在单片机延时程序中应考虑所使用的晶振的频率,在51系列的单片机中我们常用的是11.0592MHz和12.0000MHz的晶振,而在AVR单片机上常用的有8.000MHz和4.000MH的晶振所以在网上查找程序时如果涉及到精确延时则应该注意晶振的频率是多大。
冰箱的直流无刷电机控制无刷直流(BrushlessDC,BLDC)电机相对于感应电机具有很多优点。
BLDC电机支持无级变速,这可以提高能效并降低噪声。
BLDC电机的速度-扭矩特性曲线是平直的,这使电机可以在较低的速度下运行,无需消耗更高电流即可产生相同扭矩。
本文将讨论使用Microchip公司的PIC18FXX31系列单片机,进行冰箱中BLDC电机的有传感器和无传感器控制。
BLDC电机控制BLDC电机的转子上具有北极(N)和南极(S)交替排列的永磁体。
定子由刚片叠制而成,绕组线圈放置在槽里,槽沿轴边切割。
要旋转BLDC电机,应按一定顺序对定子绕组进行励磁。
为了执行换向序列,清楚转子位置非常重要。
转子位置使用嵌入定子中的霍尔效应传感器进行检测。
大多数电机会在定子的电机非驱动端嵌入三个霍尔传感器。
每当转子磁极接近霍尔传感器时,传感器会产生高电平或低电平信号,指示N或S极接近传感器。
根据这三个霍尔传感器的信号组合,可以确定准确的换向序列。
表1给出了对应于霍尔传感器输入的典型换向序列。
换向序列如表1所示,每个序列会将三相中的两相与电源连接,第三相保持开路。
图1显示了简化的BLDC电机控制框图。
在该示例中,使用Microchip公司的PIC18F2331闪存单片机来控制电源开关。
匹配驱动器用于对电源开关进行相应的门控驱动。
PIC18Fxx31系列具有6个脉宽调制(PulseWidthModulation,PWM)通道,PWM频率和占空比可进行编程。
Q0至Q5连接构成三相逆变桥。
A相、B相和C相分别与每个半H桥的中点连接,PWMO至PWM5分别控制电源开关Q0至Q5O PIC18Fxx31系列具有三个输入捕捉弓I脚,表示为IC1S IC2和IC3O输入捕捉模块具有一种工作模式,在该模式下,每次任意输入捕捉引脚上发生电平变化时,会捕捉Timer5的值。
将霍尔传感器与单片机连接时,适合使用该模式。
每次霍尔传感器发生电平变化时,将会产生中断,并捕捉Timer5的值。
占空比计算公式在电子工程和电路设计中,占空比(duty cycle)是指一个周期内有效信号的有效时长与周期的比值。
它通常以百分比或小数的形式表示,并用于描述周期性信号的活动程度。
占空比的计算公式取决于信号的类型和波形。
本文将详细介绍几种常见信号波形的占空比计算公式。
1. 方波信号方波信号是一种常见的周期性信号,其波形由高电平和低电平组成。
方波信号的占空比是高电平部分所占的时间与周期的比值。
占空比计算公式如下:占空比 = 高电平时长 / 周期例如,一个周期为10ms的方波信号,在高电平部分所占的时间为4ms,则占空比为4ms / 10ms = 0.4,即40%。
2. 正弦波信号正弦波信号是另一种常见的周期性信号,其波形呈现正弦曲线。
正弦波信号的占空比是正半周的有效时长与周期的比值。
由于正弦波信号的周期性,通常将占空比定义为正半周的时间与周期的比值的一半。
占空比计算公式如下:占空比 = 正半周时长 / (周期/2)例如,一个周期为20ms的正弦波信号,在正半周的时间为10ms,则占空比为10ms / (20ms/2) = 1,即100%。
3. PWM信号脉冲宽度调制(PWM)是一种常用的调制技术,广泛应用于电机控制、功率控制和通信系统中。
PWM信号的波形由一系列的脉冲组成,脉冲的宽度和间隔可以按照一定的规律进行调制。
PWM信号的占空比是高电平部分的宽度与周期的比值。
占空比计算公式如下:占空比 = 高电平宽度 / 周期例如,一个周期为5ms的PWM信号,高电平部分的宽度为1ms,则占空比为1ms / 5ms = 0.2,即20%。
4. 不对称波信号不对称波信号是指波形上升沿和下降沿的斜率不相等的周期性信号。
不对称波信号的占空比计算稍微复杂一些,需要分别计算上升沿和下降沿的时间。
占空比计算公式如下:占空比 = (上升沿时间 - 下降沿时间) / 周期例如,一个周期为8ms的不对称波信号,在上升沿的时间为3ms,下降沿的时间为2ms,则占空比为(3ms - 2ms) / 8ms = 0.125,即12.5%。
PIC学习心得本次心得为PIC18F25K22上的代码零、配置CPU 的特殊功能,地址从300000开始,如以下,有晶振选择,复位功能,看门狗配置,调试口rb7-rb6的配置,因为RB6-RB7为串口2的端口,需要对应为位=1才能使得他们可以用于普通io,其实单片机默认也是1.对于已经用于特殊功能的引脚,比如已经配置了引脚为I2C功能,如果要配置为普通IO时,需要将I2C失能掉,SSPXCON1=0X00;这样才能正常使用这2个IO口了如果要使单片机使用内部晶振,就需要将对应的OSCCON位置1IRCF<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=0x300003const 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 = 0x08void InterruptVectorHigh (void){_asmgoto InterruptHandlerHigh //jump to interrupt routine,goto之后的InterruptHandlerHigh函数名可以自己取名_endasm}// High priority interrupt routine#pragma code#pragma interrupt InterruptHandlerHigh //InterruptHandlerHigh函数名可以自己取名void InterruptHandlerHigh()//中断函数内容低优先级函数地址为0X18#pragma code InterruptVectorLow= 0x18void InterruptVectorLow (void){_asmgoto 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中二、ADC1、ADC采集为了不浪费MCU资源,不用中断函数来采集配置如下,(1)先将要用于ADC采集的IO口配置为输入(2)将对应IO扣配置为ADC输入(3)配置ADCON0-3寄存器TRISA|=0x01;//引脚方向寄存器,1输入,0输出。