📄 ayb380-n0-v4.0-vip.c
字号:
/************************************************
*文件名:AYB380-N0-V4.0-VIP.C
*功能:通用控制盒
*创建信息:2006年10月09日 sanjin555@126.com
*最后修改日期:2006年10月12日
*公司:上海超艺电子有限公司
************************************************/
//功能修改:从机时红色指示灯忽闪忽闪
//声音较高时,保持持续亮,使用延时标志
//功能扩展:新增加闪烁模式,旋钮可以调节闪烁频率,尚未校准09,26
//此程序已经OK,单总线终于可以精确到位了,哈哈!
#include <pic.h>
#include <delay.h>
#include <math.h>
#define key_sw RA7//手动开关
#define adc_mic RA1//麦克风A/D转换口
#define key_mod RA2//模式切换键
#define t_sign RA6//控制从机口
#define adc_sens RA0//灵敏度检测口
#define r_sign RB0//中断口与接受信号口
#define led1 RB1//灯1控制口
#define led2 RB3//灯2控制口
#define led3 RB4//灯3控制口
#define led4 RB5//灯4控制口
#define pwm_o RB2//指示灯PWM控制
#define spow_c RB6//从机电源控制口
#define indi_c RB7//指示灯电源口
//#define ON() PORTB=PORTB|0x3a //B"00111010"
//#define OFF() PORTB=PORTB&0xc5 //0b"11000101"
#define ctrlmod_addr 0x02
unsigned char ctrlmod_data,ctrlmod_count,ctr_cnt,int_count,trims_data;
unsigned char swmod_data;//向EEPROM些数据,已方便下次做主机时的模式判别
volatile unsigned char pwmdata,cmd;
persistent bit msmod_f,swmod_f,delay_f,add_f,ctrlmod_f,flash_f,flag1,slow_f,flag2,flag3;
unsigned char admic_data,adsens_data,delay_count,temp1,count,light_value,loop_times,loop_count;
unsigned char temp,tmp,c[2];
void ON(){
PORTB=PORTB|0x3a;
}
void OFF(){
PORTB=PORTB&0xc5;
}
void flash_a(void)
{PORTB=PORTB|0x12;
CCPR1L=0 ;
c[0]=0x05;
indi_c=1;}//B"00111010"
void flash_b() {
PORTB=PORTB|0x28;
CCPR1L=255;
c[0]=0x0a;
indi_c=1;} //B"00111010"
void flash_ab(){
ON();
c[0]=0xaa;
indi_c=1;
CCPR1L=50;
}
void servant(void);
void key_pro(void);
void master(void);
void transmit(void);
void mod1(unsigned char i,unsigned char j);//连闪模式的函数调用
void mod2(void);//
void mod3(void);//
void mod4(void);
void main (void)
{
// init();
//**********************************************************
OPTION=0X0F;
OSCCON=0x6F;//4Mhz
//禁用看门狗与配置系统时钟模式均可以在烧写时设置
//配置中断
TRISA=0xbf;//设置RA6为输出,其他为输入模式
TRISB=0x01;//设置RB0为输入,其他为输出模式
//中断设置
INTE=1;//开外部引脚中断
PEIE=1;//允许外部中断
INTF=0;//清外部中断标志
GIE=1; //开总中断
INTEDG=0;//下降沿触发
//ADC配置
ADCON1=0x04;//设置左对齐格式,并选择通道0、1作为转换口
//选择VCC为参考电压,具体通道在转换时才选择
//PWM配置
CCP1CON=0b11001100;//配置RB2为PWM输出
PR2=99;//设置PWM频率
T2CON=0B10000100;//使能时钟
//PWM周期=[(PR2)+ 1]*4*TOSC*(TMR2 预分频比),用时间单位表示10k
//设置PWM的占空比
spow_c=1;//开从机和所有控制设备的电源
indi_c=1;//开显示
msmod_f=1;//自设为主机模式
t_sign=1;//向下位机发信号
ctrlmod_count=0;
ctr_cnt=0;
swmod_f=0;//关电源
// ctrlmod_data = EEPROM_READ(ctrlmod_addr);////ctrlmod,声控标志位
t_sign=0;
DelayUs(10);
t_sign=0;
delay_f=1;//延时标志
//**********************************************************
while(1)
{ CLRWDT();
count++;
if(msmod_f)master();
else servant();
}
}
//*******************************************************
void master(void)
{ unsigned char temp1,temp2,delay_count;
key_pro();
if(swmod_f)//电源开
{ t_sign=1;
if(ctrlmod_count==0){
indi_c=1;
if(delay_f/*&&count==160*/) //麦克风控制模式
{
ADCON0=0x05; //时钟为f/2,选择通道1,启动转换"00001101"
while(GODONE){;}//等待转换完成
adsens_data=ADRESH+8;//采用左对齐,忽略低两位数据
CCPR1L=adsens_data/2;
ADCON0=0x0d;//时钟为f/2选择通道0,启动转换
while(GODONE){;}//等待A/D转换完毕
admic_data=ADRESH;//采用左对齐,忽略低两位数据
//****************软件调节声音的AD转换值**************
if(admic_data>adsens_data){
ON();
delay_f=1;
c[0]=0xA5;//
}
else {
slow_f=1;
light_value=15;
delay_f=0;//不延时采样
}//判断输出的大小
}
else if(slow_f){
loop_count++;
if(loop_count>15){loop_count=0;light_value--;}
if(light_value>loop_count){ON(); c[0]=0xA5;}
else {OFF(); c[0]=0xF0;}//
transmit();
key_pro();
if(light_value==1)slow_f=0;
ADCON0=0x05; //时钟为f/2,选择通道1,启动转换"00001101"
while(GODONE){;}//等待转换完成
adsens_data=ADRESH;//采用左对齐,忽略低两位数据
ADCON0=0x0d;//时钟为f/2选择通道0,启动转换
while(GODONE){;}//等待A/D转换完毕
admic_data=ADRESH;//采用左对齐,忽略低两位数据
if(admic_data>adsens_data){
light_value=17;
}
}
else if(!delay_f&&!slow_f)//关灯的时候 加快采样速度,来判断是否真的已经关掉
{
ADCON0=0x05; //时钟为f/2,选择通道1,启动转换"00001101"
while(GODONE){;}//等待转换完成
adsens_data=ADRESH+8;//采用左对齐,忽略低两位数据
CCPR1L=adsens_data/2;
ADCON0=0x0d;//时钟为f/2选择通道0,启动转换
while(GODONE){;}//等待A/D转换完毕
admic_data=ADRESH;//采用左对齐,忽略低两位数据
//****************软件调节声音的AD转换值**************
//if(admic_dat
if(admic_data>adsens_data){
ON();
delay_f=1;
c[0]=0xA5;//
}
else {
delay_f=0;//不延时采样
OFF();
c[0]=0xF0;//
}//判断输出的大小
}
// transmit();////////////////
}
else if(ctrlmod_count==1)
{ transmit();
for(delay_count=200;delay_count>0;delay_count--)
{DelayUs(250); key_pro();
}
ON();c[0]=0xA5;//显示红色色
indi_c=1;CCPR1L=100;
}
else /*if(ctrlmod_count>1)*/{
indi_c=1;
ctr_cnt++;
switch(ctrlmod_count)
{
case 0:
case 1:
case 2: mod1(2,2);break;//交叉单闪
case 3: mod1(4,6);flag2=1;break;//交叉三连闪
case 4:mod2();break;//乱闪
case 5: mod3();break;//交叉加同闪
case 6: mod1(6,10);flag2=1;break;//交叉五连闪
case 7: mod4();break;//交叉四连闪再交叉4单闪
default:break;
}
transmit();////////////////////////
ADCON0=0x0d; //时钟为f/2,选择通道1,启动转换"00001101"//????????
while(GODONE){;}//等待转换完成
adsens_data=ADRESH/8;//采用左对齐,忽略低两位数据
for(;adsens_data>0;adsens_data--){
for(delay_count=15;delay_count>0;delay_count--){
DelayUs(250);
key_pro();
}
}
if(flag2){OFF();
indi_c=0;
c[0]=0x0f;
}
transmit();/////////////////////
adsens_data=ADRESH/8;//采用左对齐,忽略低两位数据
for(;adsens_data>0;adsens_data--){
for(delay_count=20;delay_count>0;delay_count--){
// transmit();
DelayUs(250);
key_pro();
}
}
}
}
else {//电源关
OFF();
c[0]=0x07;//电源关 指示灯灭
indi_c=0;
}
if(count==8)transmit();//△1
// if(count==38)//△1
// {
// transmit();//调用发送
//count=0;
// }
}
//***************连闪模式***************
void mod1(unsigned char i,unsigned char j)
{
if(ctr_cnt<i)flash_a();
else if (ctr_cnt<j)flash_b();
if(ctr_cnt==j){ctr_cnt=0;flash_b();}
if(ctr_cnt>j)ctr_cnt=0;
}
//*************乱闪***********
void mod2 (void)
{
if(ctr_cnt<6)flash_a();
else if(ctr_cnt<11)flash_b();//B5
else if(ctr_cnt<16)flash_a();//A5
else if(ctr_cnt<21)flash_b();//B5
else if(ctr_cnt<26)flash_a();//A5
else if(ctr_cnt<31)flash_b();//B5
else if(ctr_cnt<34)flash_a();//A3
else if(ctr_cnt<37)flash_b();//B3
else if(ctr_cnt<40)flash_a();//A3
else if(ctr_cnt<43)flash_b();//B3
else if(ctr_cnt<46)flash_a();//A3
else if(ctr_cnt<49)flash_b();//B3
else if(ctr_cnt<52)flash_a();//A3
else if(ctr_cnt<55)flash_b();//B3
else if(ctr_cnt%2)flash_a();//A
else flash_b();//B3
if(ctr_cnt==72)ctr_cnt=0;
}
//**************先四连闪在单闪*****
void mod3 (void)
{
if(ctr_cnt<12&&ctr_cnt%2)flash_a();
else if(ctr_cnt<12&&(ctr_cnt%2==0))flash_b();
else if(ctr_cnt==13){flash_ab();slow_f=0;}
else if(ctr_cnt==14)flag2=1;
else if(ctr_cnt==16){flash_ab();flag2=0;}
else if(ctr_cnt==17)flag2=1;
else if(ctr_cnt==19){flash_ab();flag2=0;}
else if(ctr_cnt==20)flag2=1;
else if(ctr_cnt>21&&ctr_cnt<33&&ctr_cnt%2)flash_b();
else if(ctr_cnt>21&&ctr_cnt<33&&(ctr_cnt%2==0))flash_a();
else if(ctr_cnt==34){flash_ab();flag2=0;}
else if(ctr_cnt==35)flag2=1;
else if(ctr_cnt==37){flash_ab();flag2=0;}
else if(ctr_cnt==38)flag2=1;
else if(ctr_cnt==40){flash_ab();flag2=0;}
else if(ctr_cnt==41)flag2=1;
else if(ctr_cnt==42)ctr_cnt=0;
}
//*********************单闪*******
void mod4(void)
{
if(ctr_cnt<5)flash_a();
else if(ctr_cnt<9)flash_b();
else if(ctr_cnt<13)flash_a();
else if(ctr_cnt<17)flash_b();
else if(ctr_cnt<21)flash_a();
else if(ctr_cnt<25)flash_b();
else if(ctr_cnt%2)flash_a();
else {flash_b();}
if(ctr_cnt==36)ctr_cnt=0;
}
void transmit(void)
{ CLRWDT();
t_sign=0;
DelayUs(3);
t_sign=1;//防止因设置的问题而引起的错误
t_sign=0;
DelayUs(50);//产生中断信号并等待从机处理现场保护
trims_data=c[0];
tmp=8;
t_sign=1;//发开始标志
// DelayUs(1);
for(;tmp>0;tmp--) {
if (trims_data&0x0001) {
t_sign=1;
t_sign=1;
t_sign=1;
t_sign=1;
t_sign=1;
}
else {
t_sign=0 ;
t_sign=0 ;
t_sign=0 ;
t_sign=0 ;
t_sign=0 ;
}
DelayUs(10);
trims_data>>=1;
}
DelayUs(20);
t_sign=1;
}
void servant(void)
{ if(flag3){CCPR1L=pwmdata;
if(c[0]<0x20&&c[0]>0)indi_c=0; //按键关则关
if(add_f){ pwmdata++;
for(delay_count=20;delay_count>0;delay_count--)DelayUs(250);
if(pwmdata>100)add_f=0;
}
else {
pwmdata--;
for(delay_count=1;delay_count>0;delay_count--)DelayUs(250);
if(pwmdata==0)add_f=1;
}
}
}
//按键处理程序**************************
void key_pro(void)
{//SW键处理
unsigned char i;
if(!key_sw)
{ for(i=100;i>0;i--)DelayUs(250);
if(!key_sw){
swmod_f=!swmod_f;
OFF();
while(!key_sw);//WAITE
}
}
//控制模式键处理
if(swmod_f&&!key_mod)
{ for(i=100;i>0;i--)DelayUs(250);
if(!key_mod) {
ctrlmod_count++;//=!ctrlmod_f;
if(ctrlmod_count>7)ctrlmod_count=0;
ctr_cnt=0;
OFF();
while(!key_mod);
}
}
}
//**********按键处理结束****************
static void interrupt isr(void) //中断程序只执行一次,用来判断主从模式
{ //出现中断,表明本机应该工作在从机状态
t_sign=0;
INTE=0;//OFF外部引脚中断
PEIE=0;//NO允许外部中断
INTF=0;//清外部中断标志
GIE=0;
TRISB=0x01;//设置RB0为输入,其他为输出模式
// clear the interrupt
//关闭中断,永远不会在执行
if(msmod_f)msmod_f=0; //设置为从机模式
// DelayUs(10);
tmp=0x01;
c[0]=0;
temp1=8;
while(!r_sign);//WAIT
DelayUs(8);
t_sign=1;
for(;temp1>0;temp1--)
{ t_sign=r_sign;
if (t_sign) // "1" presented
c[0] |= tmp;
tmp=tmp<<1;
DelayUs(10);
}
DelayUs(20);
t_sign=1;
if(c[0]==0xa5){ON(); indi_c=1;flag3=1;}
else if(c[0]==0x05){flash_a(); CCPR1L=0;flag3=0;}
else if(c[0]==0x0a){flash_b(); CCPR1L=100;flag3=0;}
else if(c[0]==0xaa){flash_ab(); CCPR1L=50;flag3=0;}
else{ OFF();
if(c[0]<0x20)indi_c=0;//声控关仍然开显示
else indi_c=1;//判断是声控关还是电源关
}
int_count++;
if(int_count>100){int_count=0;
if(add_f){ pwmdata++;
if(pwmdata>100){add_f=0;pwmdata=100;}
}
else {pwmdata--;
if(pwmdata==1)add_f=1;
}
}
INTE=1;//开外部引脚中断
PEIE=1;//允许外部中断
INTF=0;//清外部中断标志
GIE=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -