📄 last.c
字号:
/**********************************
程序框架
**********************************/
#include <p18f4520.h>
#define MAXNUM 400
#define MAXNUM2 200 //最大容许分配384个字节,见连接器配置文件
unsigned char AD_flag=0; //AD转换完标志
unsigned char DATA_flag;
unsigned char databattery[2];
unsigned char datatemp[2]={0,0};
unsigned int datacount; //测量记数
unsigned char temper[2]="wd"; // 温度标志
unsigned char battery[2]="dl"; // 电量标志
#pragma udata testdata //强制将大数组分配到一个特定的区域
ram unsigned char datace[MAXNUM]; //测量数据数组
// ram unsigned char datace2[MAXNUM2]; //测量数据数组
#pragma udata
void ADinitial(void);
void serialinital(void);
void initial(void);
void datatest(void); //导轨数据测量函数
void batterytest(void);
void Testtemp(void); //温度测试
void waitidle(void); //等待IIC空闲
void IICinitial(void); //IIC初试化
void AD_isr(void); //AD中断函数
//void senddata(unsigned char *p,unsigned char *q,unsigned int num);
void senddata(unsigned char *p);
void closeoropen(unsigned char key); //电机电源开关
void control(unsigned char flag); //电机正反转控制
void ADread(); //AD读数
/******************************
函数:void reset()
电机初始化复位,并设定任何开始测量时,电机都必须在左边
*******************************/
void reset(void)
{
unsigned int i = 20000,j,p;
if(PORTDbits.RD7 == 0)
{
control(0); //控制电机左转
closeoropen(1); //开电机电源
while(PORTDbits.RD7 == 0); //等待电机到头
while(i-->0);
while(PORTDbits.RD7 == 0);
closeoropen(0); //关电机
}
}
/*****************************
函数:void timer0inition(void)
初始化为定时方式
*******************************/
void timer0inition(void)
{
T0CON=0x09; //16为定时方式,不分频,查询方式
// TMR0H=0xf5;
// TMR0L=0x26; // 延时1MS
TMR0H=0xfa;
TMR0L=0x93; //延时500us
T0CONbits.TMR0ON=0;
INTCONbits.TMR0IF=0;
}
/****************************
函数:void delay(unsigned int time)
延时
*****************************/
void delay(unsigned int time)
{
while(time--)
{
T0CONbits.TMR0ON=1;
while(INTCONbits.TMR0IF==0);
T0CONbits.TMR0ON=0;
INTCONbits.TMR0IF=0;
// TMR0H=0xf5;
// TMR0L=0x26; // 延时1MS
// TMR0H=0xfa;
// TMR0L=0x93; //延时500us
TMR0H=0xfc;
TMR0L=0xbe; //延时300us
while(PORTDbits.RD6 == 1||PORTDbits.RD7 == 1)
break;
}
}
/******************************
函数:void closeoropen(char key)
电机电源开关,'0'关,‘1’开
*******************************/
void closeoropen(unsigned char key)
{ unsigned int i = 200,j,p;
if(key == 1)
// LATBbits.LATB4 = 1; //开电机
LATBbits.LATB4 = 0; //开电机
else
// LATBbits.LATB4 = 0; // 关电机
LATBbits.LATB4 = 1; // 关电机
while(i-->0);
}
/******************************
函数:void control(char flag)
电机正反转控制,‘0’时,电机往左跑,为‘1’时电机往右跑
*******************************/
void control(unsigned char flag)
{ unsigned int i = 200,j,p;
if(flag == 1)
LATDbits.LATD4 = 1;
else
LATDbits.LATD4 = 0;
while(i-->0);
}
/******************************
函数名:initial()
单片机初试化
******************************/
void initial(void)
{
//senddata("wo shi liu hongwen",40);
INTCON=0;
PIE1=0;
PIE2=0;
PIR1=0;
PIR2=0;
RCONbits.IPEN = 0; //禁止中断优先级
TRISDbits.TRISD7 = 1; //RD7为左到头,光电管检测,配置为输入
TRISDbits.TRISD6 = 1; //RD6为右到头,光电管检测,配置为输入
TRISBbits.TRISB4 = 0; //电机电源控制总开关
TRISDbits.TRISD4 = 0; //电机正反转控制,先假设控制信号为‘0’时,电机往左跑,为‘1’时电机往右跑
PORTBbits.RB4 = 1; //切断电机电源 RB is input LAT is output
}
/*****************************
函数名:serialinitial()
串口初始化
*****************************/
void serialinital(void)
{
TXSTA=0X04;
RCSTA=0X80; //串行端口使能,异步模式下使能连续接收
TRISC=TRISC|0X80;
TRISC=TRISC&0XBF;
SPBRG=35; //11.0592M晶振时,SPBRG寄存器为35,波特率=FOSC/[16(X+1)] 波特率为19200
TXSTAbits.TXEN = 1;
RCSTAbits.CREN = 1;
}
/*******************************
函数名:IICinitial()
IIc总线初始化
********************************/
void IICinitial(void)
{
TRISCbits.TRISC3 = 1;
TRISCbits.TRISC4 = 1;
SSPCON1 = 0X28; //使能IIC串行总线,并工作在主控方式
SSPADD = 7; //定义波特率,4MHz时,时钟=4MHZ/[4*(7+1)]=0。125MHZ
SSPSTAT = 0X80; //IIC模式下,关闭标准速度方式的回转率控制
PIR1bits.SSPIF == 0;
TMR1H = 0;
TMR1L = 0;
PIR1bits.TMR1IF = 0;
}
/********************************
函数名:waitidle()
等待IIC空闲
********************************/
void waitidle(void)
{
while ((SSPCON2 & 0x1F )|(SSPSTATbits.R_W ))
continue;
}
/********************************
函数名:configtcn75(unsigned char cmd)
配置TCN75
*********************************/
void configtcn75(unsigned char cmd)
{
SSPSTATbits.CKE = 1;
SSPCON2bits.SEN = 1; //启动IIC
while(SSPCON2bits.SEN == 1); //等待IIC空闲将它设为1
SSPBUF = 0x90; //写TCN75器件地址
waitidle();
while(SSPCON2bits.ACKSTAT == 1); //等待应答
SSPBUF = 0x01; //写TCN75配制寄存器config地址
waitidle();
while(SSPCON2bits.ACKSTAT == 1); //等待应答
SSPBUF = cmd; //写TCN75配制寄存器config内容
waitidle();
while(SSPCON2bits.ACKSTAT == 1); //等待应答
SSPCON2bits.PEN = 1;
while(SSPCON2bits.PEN == 1); //发送停止位
}
/********************************
函数名:Testtemp()
启动温度测试
********************************/
void Testtemp(void)
{
unsigned char str[]="wd";
unsigned char temp,readdata = 0;
unsigned char cmd_byte = 0x01;
unsigned int j;
IICinitial();
configtcn75(0xE0); //连续测量模式
while(1)
{
SSPSTATbits.CKE = 1;
SSPCON2bits.SEN = 1; //启动IIC
while(SSPCON2bits.SEN == 1); //等待IIC空闲将它设为1
SSPBUF = 0x90; //写TCN75器件地址
waitidle();
while(SSPCON2bits.ACKSTAT == 1); //等待应答
SSPBUF = cmd_byte; //写TCN75配制寄存器config地址
waitidle();
while(SSPCON2bits.ACKSTAT == 1); //等待应答
SSPCON2bits.RSEN = 1; //重新发起始信号
while(SSPCON2bits.RSEN == 1);
SSPBUF = 0X91; //读TCN75
waitidle();
while(SSPCON2bits.ACKSTAT == 1);
SSPCON2bits.RCEN = 1; //容许接收
while(SSPCON2bits.RCEN == 1);
while(!SSPSTATbits.BF);
readdata = SSPBUF;
if(cmd_byte == 0)
{
SSPCON2bits.ACKDT = 0;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN == 1);
SSPCON2bits.RCEN = 1; //容许接收
while(SSPCON2bits.RCEN == 1);
while(!SSPSTATbits.BF);
temp = SSPBUF;
}
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN == 1);
SSPCON2bits.PEN = 1;
while(SSPCON2bits.PEN == 1); //发送停止位
if(cmd_byte == 0) break;
if(readdata & 0x80)
cmd_byte = 0x01;
else
cmd_byte = 0x00;
}
senddata(temper);
datatemp[1]=readdata;
senddata(datatemp);
TXREG = 0xaa;
while(PIR1bits.TXIF == 0); //等待串口发送完成
for(j = 300;j > 0;j--);
// senddata(&readdata,str,1);
/* TXREG = '#' ;
while(PIR1bits.TXIF == 0); //等待串口发送完成
for(j = 300;j > 0;j--);
TXREG = readdata ;
while(PIR1bits.TXIF == 0); //等待串口发送完成
for(j = 300;j > 0;j--);
// senddata(datatemp);
// senddata(end);
TXREG = 0xaa;
while(PIR1bits.TXIF == 0); //等待串口发送完成
for(j = 300;j > 0;j--);
*/
}
/******************************
函数名:ADinitial()
AD初始化
*******************************/
void ADinitial(void)
{
// ADCON0 = 0X00; //选择通道0
// ADCON0 = 0X04; //选择通道1
ADCON1 = 0X3D; //选择只有通道0,1为模拟输入,其它的为数字IO,采用外部基准电压源
ADCON2 = 0XB1;
PIE1bits.ADIE=0; //AD中断不容许
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -