📄 copy av matrix.c
字号:
//程序的调试可以用"串口调试助手V2.1"辅助完成2008.2.10.20.24
#include "p18cxxx.h"
//#include "p18f6585.h"
#include <timers.h>
#pragma config OSC = XT, OSCS = OFF
#pragma config PWRT = ON
#pragma config WDTPS =32768
#pragma config CCP2MX = ON
#pragma config MCLRE = OFF
#pragma config BOR = ON //RC2 OK
#pragma config BORV = 27
#pragma config WDT = ON
#pragma config LVP = OFF
#define on 0
#define off 1
#define RESET_8816 PORTGbits.RG0
#define STROBE_8816 PORTGbits.RG1
#define CS11_8816 PORTGbits.RG2
#define CS21_8816 PORTGbits.RG3
#define CS31_8816 PORTGbits.RG4
#define Rs232_Out PORTCbits.RC2
void InterruptHandlerHigh(void); //中断服务程序
void timer_isr (void); //中断服务程序
void Tx_Sing_State(void);
void sound_check(unsigned char ch);
void lock_Ch(unsigned char lock);
void Cmd_see_about(void);//查询命令处理并(调试时)发送应答信息
void ctrl_8816(unsigned char D,unsigned char Y,unsigned char X);
void Cmd_return (void); //设置命令处理并发送应答信息
unsigned char RC_s[10];//字符数组
unsigned char SignalList[3]={0,0,0};
unsigned char Err;
unsigned char Ch_See;
unsigned char Ch_lock;
static unsigned char RC_Count;//232接受字节记计数
unsigned char byte_Count;//字符数组的长度数
static unsigned char TX_Count;//232发送字节记计数
static unsigned char RC_Over;//232接受超时
static unsigned int delay_count;//定时计数
/*
* For PIC18xxxx devices, the low interrupt vector is found at 000000018h.
* Change the default code section to the absolute code section named
* low_vector located at address 0x18.
*/
//底优先级中断向量
#pragma code low_vector=0x18
void low_interrupt (void)
{
/*
* Inline assembly that will jump to the ISR.
*/
_asm GOTO timer_isr _endasm //跳到低优先级中断程序
}
/*
* Returns the compiler to the default code section.
*/
#pragma code
/*
* Specifies the function timer_isr as a low-priority interrupt service
* routine. This is required in order for the compiler to generate a
* RETFIE instruction instead of a RETURN instruction for the timer_isr
* function.
*/
#pragma interruptlow timer_isr
/*
* Define the timer_isr function. Notice that it does not take any
* parameters, and does not return anything (as required by ISRs).
*/
void
timer_isr (void)
{
/*
* Clears the TMR0 interrupt flag to stop the program from processing the
* same interrupt multiple times.
*/
INTCONbits.TMR0IF = 0; //Clear Timer0 overflow flag
T0CONbits.TMR0ON = 0; //8ms超时,停止TMR0,停止限时监控
//下面写用户程序
RC_Over = 1; //产生超时事件
byte_Count = RC_Count; //保存接受字符数
RC_Count = 0; //准备再次接受串行口信号
}
//高优先级中断向量
#pragma code InterruptVectorHigh=0x08
void InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh //跳到高优先级中断程序
_endasm
}
//高优先级中断服务程序
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
while(PIR1bits.RCIF==1) //若接收中断标志不为1,返回
{
PIR1bits.RCIF=0;
RC_s[RC_Count++]=RCREG; //将接收到的数据放入RC_s[]
TMR0L = 0; // Reset Timer0 to 0x0000
T0CONbits.TMR0ON = 1; // 起动限时监控
}
if((TX_Count<byte_Count)&&(PIE1bits.TXIE)) //需要发送
{
if(PIR1bits.TXIF==1){ //若缓冲空
TXREG=RC_s[TX_Count++]; //发送一个字节,发送计数加一
}
if(TX_Count==byte_Count){ //不需要发送
PIE1bits.TXIE=0; //发送中断不使能
TX_Count=0; //准备再次发送记数
byte_Count=0;
}
}
}
//初始化程序
void
OpenUart(void)
{
SPBRG=0x19; //选择传输波特率为9600bps
TXSTA=0X04; //选择异步高速方式传输8位数据
RCSTA=0X80; //允许异步串行口工作
TRISC=0X80; //将RC7,RC6设置为输入
BAUDCONbits.BRG16=0; //高速波特率
TXSTAbits.TXEN=1; //发送允许
RCSTAbits.CREN=1; //接受允许
PIE1bits.RCIE=1; //接收中断使能
IPR1bits.RCIP=1; //接受高中断优先级中断使能
IPR1bits.TXIP=1; //发送高中断优先级中断使能
RC_Count=0;
RC_Over=0;
TX_Count=0;
}
void OpenMyTimer0(unsigned char config)
{
T0CON = (0x7f & config); // Configure timer, but don't start it yet
INTCONbits.T0IF = 0; // Clear Timer0 overflow flag
INTCONbits.T0IE = 1; // Enable Timer0 overflow interrupt
INTCON2bits.TMR0IP=0; //TMR0低中断优先级中断使能
TMR0H = 0x70; //定时器高八位
TMR0L = 0; // Reset Timer0 to 0x7000
}
void test(void){
static unsigned char t;
RC_s[0]=0;
RC_s[1]=0;
RC_s[2]=t++;RC_s[3]=0;RC_s[4]=0;
byte_Count=5;
}
void send(void){
PIE1bits.TXIE=1; //发送中断使能,232发送
while(PIE1bits.TXIE==1)
{_asm CLRWDT _endasm} //忙等待
}
//主程序
void
main(void)
{
_asm CLRWDT _endasm
TRISE=0XFF; //声音信号检测位输入使能S0~S6
TRISD=0X7F; //声音信号检测位输入使能S20~S26
TRISB=0XFF; //声音信号检测位输入使能S30~S36
CMCON=7; //RF3:6 IS I/O
ADCON1=0X7F; //AN0:15 IS I/O
TRISF=0X00; //F0-F7---AX0-AX3,AY0-AY2,DATE
PORTF=0;
TRISG=0X00; //RG0:RESAT,RG1:STROBE,RG2:CS11,RG3:CS21,RG4:CS31,
delay_count=0XFFFF; //软件定时器初始值
Ch_See=0; //监控外部节点信号初始值
RESET_8816=1; //8816复位,切断8816内部连接
CS11_8816=0; //8816复位CS,不选中
CS21_8816=0; //8816复位CS,不选中
CS31_8816=0; //8816复位CS,不选中
RESET_8816=0; //8816复位结束
RCONbits.IPEN=1; //使能中断优先级
OpenUart(); //建立串口通信条件
OpenMyTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT);//建立串口通信限时条件
INTCON|=0XC0; //总中断和外围中断允许
//循环执行任务
for(;;){ //test();
_asm CLRWDT _endasm
lock_Ch(Ch_lock);
//定时事件处理
if(--delay_count==0){
delay_count=0XFFFF; //定时1秒左右
PORTDbits.RD7=~PORTDbits.RD7; //LED FLASH
if(Ch_See==0){
/*
Tx_Sing_State();//无查询命令定时发送外部《声音信号》全部信息
send();
*/
;
}
else{
sound_check(Ch_See); //有查询命令定时发送指定查询信息
send();
}
}
//232接收事件处理
if(RC_Over==1){
_asm CLRWDT _endasm
//_asm CLRWDT _endasm
if(RC_s[0]==1){ //是查询命令
Cmd_see_about(); //查询命令处理
//在定时工作程序中,sound_check(channels);定时发送
}
else
if(RC_s[0]==3){ //是设置命令
Ch_See=0; //停止定时发送指定查询信息
ctrl_8816(RC_s[1],RC_s[2],9); //8816通道控制程序
if(RC_s[1]==5)Ch_lock=RC_s[2];
if(RC_s[1]==7)Ch_lock=0;
//test();//设置命令处理
Cmd_return();//设置命令处理
send();
}
else //是非法代码
{
Ch_See=0; //停止定时发送指定查询信息
RC_s[0]=1;RC_s[1]=2;RC_s[2]=3;RC_s[3]=4;RC_s[4]=5;byte_Count=5;
send();
}
RC_Over=0; //清除232接受结束事件标志
}
}
//循环执行任务
}
void
Tx_Sing_State (void) //定时发送外部《声音信号》信息
{//状态回复指令<有语音>:02 bb bb bb 01 (注意:下位机定时发送。)
RC_s[0]=2;
RC_s[1]=PORTB; //S21~s15
RC_s[1]&=0X7F;
RC_s[2]=PORTD; //s15~S8
RC_s[2]&=0X7F;
RC_s[3]=PORTE; //s8~S1
RC_s[3]&=0X7F;
RC_s[4]=1;
byte_Count=5;
}
void
lock_Ch(unsigned char lock)
{
switch(lock){
case 0: Rs232_Out=1;break;
case 1: Rs232_Out=PORTEbits.RE0;break;
case 2: Rs232_Out=PORTEbits.RE1;break;
case 3: Rs232_Out=PORTEbits.RE2;break;
case 4: Rs232_Out=PORTEbits.RE3;break;
case 5: Rs232_Out=PORTEbits.RE4;break;
case 6: Rs232_Out=PORTEbits.RE5;break;
case 7: Rs232_Out=PORTEbits.RE6;break;
case 8: Rs232_Out=PORTDbits.RD0;break;
case 9: Rs232_Out=PORTDbits.RD1;break;
case 10: Rs232_Out=PORTDbits.RD2;break;
case 11: Rs232_Out=PORTDbits.RD3;break;
case 12: Rs232_Out=PORTDbits.RD4;break;
case 13: Rs232_Out=PORTDbits.RD5;break;
case 14: Rs232_Out=PORTDbits.RD6;break;
case 15: Rs232_Out=PORTBbits.RB0;break;
case 16: Rs232_Out=PORTBbits.RB1;break;
case 17: Rs232_Out=PORTBbits.RB2;break;
case 18: Rs232_Out=PORTBbits.RB3;break;
case 19: Rs232_Out=PORTBbits.RB4;break;
case 20: Rs232_Out=PORTBbits.RB5;break;
case 21: Rs232_Out=PORTBbits.RB6;break;
default: break;
}
}
void
sound_check(unsigned char ch)
{
RC_s[0]=2;RC_s[4]=1;byte_Count=5; //状态回复指令
// 状态回复指令<有语音>:02 02 bb bb 01 (注意:下位机定时发送。)
// 状态回复指令<无语音>:02 03 bb bb 01 (注意:下位机定时发送。)
switch(ch){
case 1: if(PORTEbits.RE0==on)RC_s[1]=2;else RC_s[1]=3;break;
case 2: if(PORTEbits.RE1==on)RC_s[1]=2;else RC_s[1]=3;break;
case 3: if(PORTEbits.RE2==on)RC_s[1]=2;else RC_s[1]=3;break;
case 4: if(PORTEbits.RE3==on)RC_s[1]=2;else RC_s[1]=3;break;
case 5: if(PORTEbits.RE4==on)RC_s[1]=2;else RC_s[1]=3;break;
case 6: if(PORTEbits.RE5==on)RC_s[1]=2;else RC_s[1]=3;break;
case 7: if(PORTEbits.RE6==on)RC_s[1]=2;else RC_s[1]=3;break;
case 8: if(PORTDbits.RD0==on)RC_s[1]=2;else RC_s[1]=3;break;
case 9: if(PORTDbits.RD1==on)RC_s[1]=2;else RC_s[1]=3;break;
case 10: if(PORTDbits.RD2==on)RC_s[1]=2;else RC_s[1]=3;break;
case 11: if(PORTDbits.RD3==on)RC_s[1]=2;else RC_s[1]=3;break;
case 12: if(PORTDbits.RD4==on)RC_s[1]=2;else RC_s[1]=3;break;
case 13: if(PORTDbits.RD5==on)RC_s[1]=2;else RC_s[1]=3;break;
case 14: if(PORTDbits.RD6==on)RC_s[1]=2;else RC_s[1]=3;break;
case 15: if(PORTBbits.RB0==on)RC_s[1]=2;else RC_s[1]=3;break;
case 16: if(PORTBbits.RB1==on)RC_s[1]=2;else RC_s[1]=3;break;
case 17: if(PORTBbits.RB2==on)RC_s[1]=2;else RC_s[1]=3;break;
case 18: if(PORTBbits.RB3==on)RC_s[1]=2;else RC_s[1]=3;break;
case 19: if(PORTBbits.RB4==on)RC_s[1]=2;else RC_s[1]=3;break;
case 20: if(PORTBbits.RB5==on)RC_s[1]=2;else RC_s[1]=3;break;
case 21: if(PORTBbits.RB6==on)RC_s[1]=2;else RC_s[1]=3;break;
default: break;
}
}
void
Cmd_see_about(void) //查询命令处理并(调试时)发送应答信息
{
if((RC_s[2]<1)||(RC_s[2]>21))//查错
goto Cmd_see_about_Err;
if(RC_s[1]==1){ //指令正确
Ch_See=RC_s[2]; //建立监察点
//En_see_bit(); //加入到表
goto Cmd_see_about_End;
}
else
if(RC_s[1]==3){ //指令正确
Ch_See=0; //消除监察点
//Dn_see_bit(); //从表消除
goto Cmd_see_about_End;
}
Cmd_see_about_Err:
RC_s[0]=2;RC_s[1]=4;RC_s[4]=1;byte_Count=5; //查询错误指令:02 04 bb bb 01
Ch_See=0;
send();
Cmd_see_about_End:
;
}
//ctrl_8816(RC_s[1],RC_s[2],9); //8816通道控制程序
void
ctrl_8816(unsigned char D,unsigned char Y,unsigned char X ){
//D=1连接/0不连接
//X 节点1
//Y 节点2
unsigned char Decoder;
//SET CS High
//Set Address
//Set STROBE High
if((Y>=1)&&(Y<=7)){
CS11_8816=1;
Decoder=Y-1;
}
else if((Y>=8)&&(Y<=14)){
CS21_8816=1;
Decoder=Y-8;
}
else if((Y>=15)&&(Y<=21)){
CS31_8816=1;
Decoder=Y-15;
}
Decoder<<=4;
Decoder+=X;
//Set DATA High/low (On/Off)
if(D==5) Decoder=Decoder|0X80;
else if(D==7) Decoder=Decoder&0X7F;
else goto eee;
PORTF=Decoder;
STROBE_8816=1;
_asm NOP _endasm
//Set STROBE falling
STROBE_8816=0;
eee:
PORTF=0X0;
//SET CS low 8816复位CS,不选中
CS11_8816=0;
CS21_8816=0;
CS31_8816=0;
}
void
Cmd_return(void)//回答上位机发送的对8816的控制指令
{
//下面是回答上位机发送的对8816的控制指令
// 请求录音指令:03 05 bb bb 04 //上位机发送指令
// 录音回复指令:04 06 bb bb 03
if((RC_s[1]==5)&&(RC_s[4]==4)){
RC_s[0]=4; RC_s[1]=6; RC_s[4]=3;
}
// 停止录音指令:03 07 bb bb 04 //上位机发送指令
// 停止回复指令:04 08 bb bb 03
else if((RC_s[1]==7)&&(RC_s[4]==4)){
RC_s[0]=4; RC_s[1]=8; RC_s[4]=3;
}
else {
// 设置错误指令:04 09 bb bb 03
RC_s[0]=4; RC_s[1]=9; RC_s[4]=3;
}
byte_Count=5;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -