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;      //清0
DADh=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;      //中断使能
qq攻防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.125M
SSPSTAT=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;      //使能UART
TRISC6=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(SS
PIF==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(); 
}     
}

本文发布于:2024-09-20 23:29:37,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/399672.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:发送   中断   函数   串口
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议