📄 testportb.c
字号:
//PORTB电平变化中断测试程序
//创建人:袁伟东
//创建日期:2008.9.18
//发送CAN数据驱动机械手
//头文件
#include "pic18.h"
#include "pic18fxx8.h"
//声明脉冲输出口位地址的计算表达式
#define PORTBIT(add,bit) ((unsigned)(&add)*8+(bit))
//脉冲位定义
volatile bit Pulse@PORTBIT(PORTC,1);
//转向位定义
volatile bit Dir@PORTBIT(PORTC,2);
//电磁铁通电位定义
volatile bit Current@PORTBIT(PORTA,0);
//定义从AGV拿工件还是放工件到AGV标志位
volatile bit Job_flag=0;
//定义检测到AGV标志位
volatile bit AGV_flag=0;
//定义加工区空闲标志位
//volatile bit Busy_flag=0;
//定义输入缓冲区待加工工件数
//int JobNum=0;
//定义脉冲步数计数单元
volatile long StepNum;
//定义模拟工件加工时间(5s)的变量
volatile int secnum=5;
//CAN接收数据标志位
//volatile bit CANreceive_flag = 0; //=1接收到CAN 数据,=0未接收到数据
//芯片配置字
//振荡器为HS(20M),系统振荡器时钟转换选择禁止
__CONFIG(1,0xFAFF);
//监视定时器WDT禁止,掉电锁定复位硬件使能,复位电压为2.7V,上电定时器使能
__CONFIG(2,0xFEFA);
//使能RB6、RB7为专用调试器接口,堆栈溢出复位使能,低压编程禁止
__CONFIG(4,0xFF7B);
//程序存储区、数据EEPROM,引导区都无代码保护
__CONFIG(5,0xFFFF);
//程序存储区、数据EEPROM,引导区、配置寄存器都无写保护
__CONFIG(6,0xFFFF);
//程序存储区、引导区都无表读保护
__CONFIG(7,0xFFFF);
//用户标识符定义
#define Fosc 20000000 //晶振为20MHZ
#define FCY 5000000 //晶振为20MHZ,FCY=20M/4=5M
#define BAUDRATE 9600 //波特率为9600
#define MILLISEC FCY/10000 //1 mSec delay constant
//声明系统初始化子函数
void init(void);
//声明CAN初始化
// void InitCAN(void);
//声明PORTB中断初始化
void InitPORTB_ISR(void);
//声明正转90度子函数
void ZZ90(void);
//声明反转90度子函数
void FZ90(void);
//声明短延时子函数
void ShortDelay(unsigned int n);
//声明长延时子函数
void LongDelay(unsigned int N);
//为避免LongDelay(unsigned int N)同时被中断函数和主函数
//调用而设置的延时函数,其内容与LongDelay一样
void DelayNmSec(unsigned int N);
//声明电磁铁通电子函数
void TongDian(void);
//声明电磁铁断电子函数
void DuanDian(void);
//声明定时器初始化子函数
//void InitTMR0(void);
//声明高优先级中断响应子函数
void interrupt HI_ISR(void);
//声明低优先级中断响应子函数
void interrupt low_priority LOW_ISR(void);
//声明从AGV搬运工件至输入缓冲区A子函数
void AGV_A(void);
//声明从AGV搬运工件至加工区B子函数
//void AGV_B(void);
//声明从输入缓冲区A搬运工件至加工区B子函数
//void A_B(void);
//声明加工区B搬运工件至输出缓冲区C子函数
//void B_C(void);
//声明从输出缓冲区C搬运工件至AGV子函数
//void C_AGV(void);
//系统初始化子函数
void init(void)
{
IPEN=1; //使能中断优先级
GIEH=1; //开放所有高优先级中断
GIEL=1; //开放所有低优先级中断
PORTA = 0x00;
LATA = 0x00;
ADCON1 = 0x07; //关闭模拟通道,使之为数字通道
TRISA0 = 0; //A口为电磁铁通电输出口
PORTB = 0x00;
LATB = 0x00;
PORTC=0x00; //清C口
LATC=0x00; //清数据输出锁存
//TRISC0=1; //S2键输入代表从AGV拿工件还是放工件到AGV的信息
TRISC1=0; //RC1作为脉冲输出口
TRISC2=0; //RC2作为转向输出口
PORTD=0x00; //清D口
LATD=0x00; //清数据输出锁存
CMCON=0x07; //关比较器
//TRISD0=1; //S1键输入检测到AGV的信号
//TRISD1=0; //RD1作为电磁铁通电口
}
//CAN初始化子函数
/*void InitCAN(void)
{
TRISB2 = 0; //设置CANRX-RB3输入,CANTX-RB2输出
TRISB3 = 1;
CANCON = 0x80; //请求配置方式
while((CANSTAT&0x80) != 0x80); //等待进入配置模式
//设置CAN波特率125kbps,在Fosc=20MHz时,Tbit=8us,假设BRP=09h
//则Tq=[2*(1+BRP)]/Fosc=2*(1+9)/(20MHz)=1us
//Tbit=8Tq,SJW=00,Sync_Seg=1Tq,Prog_Seg=1Tq
//Phase_Seg1=3Tq,Phase_Seg2=3Tq
//总线过滤器用于唤醒
BRGCON1 = 0x09;
BRGCON2 = 0x90;
BRGCON3 = 0x42;
RXB0CON = 0x60; //接收所有信息(包括错误信息),这样就不需要设置过滤屏蔽器了
RXB1CON = RXB0CON; //做同样处理
CIOCON = 0x00; //当“隐性”时,CANTX引脚驱动到高阻状态,禁止CAN捕捉
CANCON = 0x00; //请求正常方式
while((CANSTAT&0x80) != 0x00); //等待进入正常模式
//初始化CAN的中断,PIR3为CAN的外围中断标志寄存器
RXB0IF = 0; //CAN接收缓冲器0中断标志位清零
RXB0IE = 1; //使能CAN接收缓冲器0的接收中断
RXB0IP = 1; //接收缓冲器0的接收中断为高优先级
NOP();
}*/
//PORTB_ISR初始化子函数
void InitPORTB_ISR(void)
{
TRISB4=1; //RB4作为电平变化输入口
RBIE=1; //使能RB电平变化中断
RBIF=0; //清电平变化中断标志
RBPU=0; //使能弱上拉功能
RBIP=0; //置电平变化中断为低优先级中断
PORTB=PORTB; //设置PORTB端口电平变化初始条件
}
//高优先级中断响应子函数
/*void interrupt HI_ISR(void)
{
di();
if((RXB0IF == 1)&&(RXB0IE == 1)) //接收到从CAN总线发送过来的数据
{
//CANreceive_flag = 1; //置接收到CAN数据
RXB0IF = 0; //清接收中断标志
RXB0FUL = 0; //打开接收缓冲器接收新信息
Job_flag = RXB0D10; //设置取还是放工件标志位
}
ei();
}*/
//低优先级中断响应子函数
void interrupt low_priority LOW_ISR(void)
{
di();
if(RBIF==1)
{
RBIF=0; //清中断标志
AGV_flag = RB4; //将RB4口电平读入AGV_flag
}
if(AGV_flag==1)
{
AGV_A();
}
ei();
}
//步进电机正转90度c源程序
//PIC18F458晶振20MHz,要求转90度,采用40细分,步距角0.045度,
//减速器减速比1:20,步数=(90/0.045)*20=40000,电平翻转次数=80000,
//2s转90度,即40000/2=20000pps,故一个脉冲用时1/20000=50us。
//发占空比60%的方波,负脉冲脉宽20us,由延时程序控制。
void ZZ90(void)
{
Dir=0; //正转
for(StepNum=80000;StepNum>0;StepNum--) //40000个脉冲,电平翻转80000次
{
if(StepNum%2==0) //发30us高电平
{
Pulse=1;
ShortDelay(15);
}
else //发20us低电平
{
Pulse=0;
ShortDelay(10);
}
}
}
//步进电机反转90度c源程序
//PIC18F458晶振20MHz,要求转90度,采用40细分,步距角0.045度,
//减速器减速比1:20,步数=(90/0.045)*20=40000,电平翻转//次数=80000,
//2s转90度,即40000/2=20000pps,故一个脉冲用时1/20000=50us。
//发占空比60%的方波,负脉冲脉宽20us,由延时程序控制。
void FZ90(void)
{
Dir=1; //反转
for(StepNum=80000;StepNum>0;StepNum--) //40000个脉冲,电平翻转80000次
{
if(StepNum%2==0) //发30us高电平
{
Pulse=1;
ShortDelay(15);
}
else //发20us低电平
{
Pulse=0;
ShortDelay(10);
}
}
}
//短延时程序
//此延时程序编译后循环执行一次大约10条指令,20MHz的晶振,指令周期为4/20=0.2us,故循环执行一次约2us。
//延时n*2us,最大延时131ms。
void ShortDelay(unsigned int n)
{
while(--n){;}
}
//长延时程序
//延时N*1ms,最大65.5秒
void LongDelay(unsigned int N)
{
unsigned int j;
while(N--)
for(j=0;j<MILLISEC;j++);
}
//主函数中使用的延时程序
void DelayNmSec(unsigned int N)
{
unsigned int j;
while(N--)
for(j=0;j<MILLISEC;j++);
}
//电磁铁通电子函数
//电磁铁通电抓取工件
void TongDian(void)
{
Current=1; //电磁铁通电,实为控制继电器吸合
}
//电磁铁断电子函数
//电磁铁断电释放工件
void DuanDian(void)
{
Current=0; //电磁铁断电,实为控制继电器释放
}
//从AGV搬运工件至输入缓冲区A
//动作过程:A—反转90度—AGV—延时2s—通电—延时2s—正转90度—A—延时2s—断电—延时2s
void AGV_A(void)
{
FZ90();
LongDelay(2000);
TongDian();
LongDelay(2000);
ZZ90();
LongDelay(2000);
DuanDian();
LongDelay(2000);
}
//从输出缓冲区C搬运工件至AGV子函数
//动作过程:A—正转180度—C—延时2s—通电—延时2s—正转90度—AGV—延时2s—断电—延时2s—正转90度—A—延时2s
/*void C_AGV(void)
{
ZZ90();
ZZ90();
LongDelay(2000);
TongDian();
LongDelay(2000);
ZZ90();
LongDelay(2000);
DuanDian();
LongDelay(2000);
ZZ90();
LongDelay(2000);
}*/
//主函数
void main(void)
{
init(); //系统初始化
//InitCAN(); //内部CAN寄存器设置初始化
InitPORTB_ISR(); //PORTB电平变化初始化
while(1)
{
;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -