Tillkom en fråga till gällande 16F1937 numera. Har eg bara ett problem kvar att lösa
Jag läser ett "väldigt" snabbt förlopp med ADCn vilket den inte verkar hinna med helt enkelt. Har kretsen inställd på 16MHz vad jag kan se.
Pulsen på bilden är den som sker på matningsspänningen när man låser upp bildörren. Denna försöker jag detektera hela tiden så ofta som möjligt. Amplituden är ca 800mV men tiden är i bästa fall ca 10us. Kan jag ens detektera denna signal
Ser att denna PIC har en neg komparator ingång på denna pinne. Den kanske man kan använda för att kunna snabbare detektera?
Eller några andra bra ideer?
Koden som annars funkar bra bifogas också
Kod: Markera allt
//Rev Hist
//R2.1, New mcu 16F1937
#define LED_RFstat PORTD.F6
#define LED_Stat PORTD.F7
#define RF_EN PORTD.F1
#define CAN_stby PORTB.F4
#define Vbat_adc PORTA.F1
#define SDO PORTE.F2
#define SIM800_rst PORTD.F0
#define Int1 PORTE.F0
char AT[]="AT"; // To initialize mode
char noecho[]="ATE0"; // To stop echo
char mode_text[]="AT+CMGF=1"; // to set text mode
char char_mode[]="AT+CSCS=\"GSM\""; // to set character mode
char param[]="AT+CSMP=17,167,0,0"; // set the parameter of character
char mobile_no[]="AT+CMGS=\"+46723970467\""; //use to set receinpent number and mesg
char mobile_no1[]="AT+CMGS=\"+46xxxxxxxxxx\""; //use to set receinpent number and mesg
char terminator=0x1A; // chartacter form of control + z terminator character
int prio_counter=0, l=0, b=0, j=0, y=0, i=0, m=0, n=0, Vbat, Int1Value, VbatOld, VbatCalc ;
long int k=0;
unsigned short DevID;
//Warning messages to be sent thru SMS
char mesg0[]="GSM Bil OK Rev2.1";
char mesg1[]="!!**INBROTT i Bilen**!!";
char mesg2[]="Svagt bilbatteri";
//function to write anything serially.
void send_to_modem(char *s){
while(*s)
UART1_WRITE(*s++);
UART1_WRITE(0X0D);
}
void send_to_modem1(char *s){
while(*s)
UART1_WRITE(*s++);
}
//Send different message
void send_sms(int b){
if(b==0)
send_to_modem1(mesg0);
else if(b==1)
send_to_modem1(mesg1);
else if(b==2)
send_to_modem1(mesg2);
delay_ms(100);
uart1_write(terminator);
delay_ms(1000);
}
void Send_GSM(){
send_to_modem(AT);
delay_ms(2000);
send_to_modem(noecho);
delay_ms(2000);
send_to_modem(mode_text);
delay_ms(2000);
send_to_modem(mobile_no);
delay_ms(2000);
send_sms(b);
}
//Reset commands to reset adxl345 output
void ADXL345_Reset(){
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x30);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
}
//ADX345 setup
void ADXL345_init(){
//Read out device id ocf the ADXL345 chip. By sniffing the I2C, the
//device id should be seen as 229
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x00);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Set power control to normal.
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x2D);
I2C1_Wr(0x08);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Set tap axes. Use xyz axis
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x2A);
I2C1_Wr(0x01);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Set threshold for single tap detection
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x1D);
I2C1_Wr(5); //(40) iinnan
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Set the duration for single tap detection
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x21);
I2C1_Wr(32); //625us/LSB
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Set the latency for single tap detection, disable double tap
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x22);
I2C1_Wr(0);
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Map single tap interupt to INT1 pin
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x2F);
I2C1_Wr(0x00); //00000000
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Enable INT1
I2C1_Start();
I2C1_Wr(0xA6);
I2C1_Wr(0x2E);
I2C1_Wr(0x40); //01000000
I2C1_Repeated_Start();
I2C1_Wr(0xA7);
DevID=I2C1_Rd(0);
I2C1_Stop();
//Reset INT1 output if needed
ADXL345_Reset();
}
void Init_Main(){
OSCCON=0b01111000; //Set 16MHz clock 0b01110110
TRISA=0b00000010;
TRISB=0b00011000;
TRISC=0b10000000;
TRISD=0b00000000;
TRISE=0b00000011;
ANSELA=0b00000010;
ANSELB=0b00000000;
ANSELD=0b00000000;
ANSELE=0b00000001;
SDO=0; // do not alter to avoid short circuit!!!!!
UART1_Init(9600);
I2C1_Init(100000);
ADC_Init();
for(l=0; l<7; l++){
LED_Stat=1;
LED_RFstat=1;
Delay_ms(50);
LED_Stat=0;
LED_RFstat=0;
Delay_ms(50);
}
ADXL345_Init();
//Send startupSMS and set b=1 for sms2
LED_Stat=1;
LED_RFstat=1;
RF_EN=1;
Delay_ms(100);
SIM800_rst=1;
Delay_ms(35000); //Gsm net search
// Send_GSM();
Delay_ms(20000); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
ADXL345_Reset();
}
//Led blink in normal mode
void Led(){
if(k==9000)
LED_Stat=1;
if(k==500)
LED_Stat=0;
if(k==12000)
k=0;
k++;
}
void Read_ADXL345(){
Int1Value=ADC_Read(5);
if(Int1Value>511){ //2,5V
//Send SMS. Max 1 time
ADXL345_Reset();
if(m<1){
Delay_ms(10);
m++;
LED_Stat=1;
LED_RFstat=1;
RF_EN=1;
Delay_ms(100);
SIM800_rst=1;
Delay_ms(35000); //Gsm net search
// Send_GSM();
Delay_ms(1000);
// Send_GSM();
Delay_ms(20000);
}
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
ADXL345_Reset;
}
}
void Read_Vbat(){
Vbat=ADC_Read(1);
if(Vbat>895){ //14V
Delay_ms(3000);
//engine started
while(Vbat>895){
Vbat=ADC_Read(1);
LED_Stat=1;
Delay_ms(100);
LED_Stat=0;
Delay_ms(100);
m=0;
n=0;
}
while(j<450){ //Step out time ~5min
j++;
LED_Stat=1;
Delay_ms(400);
LED_Stat=0;
Delay_ms(400);
}
j=0;
//Reset INT1 output
ADXL345_Reset();
}
VbatOld=Vbat;
Vbat=ADC_Read(1);
VbatCalc=VbatOld-Vbat;
//Send sms, low battery
if(Vbat<703){ //<11.5V
Delay_ms(10000);
Vbat=ADC_Read(1);
VbatOld=Vbat;
Vbat=ADC_Read(1);
VbatCalc=VbatOld-Vbat;
if((Vbat<775)&&(n==0)){
n++;
b=2;
LED_Stat=1;
LED_RFstat=1;
RF_EN=1;
Delay_ms(100);
SIM800_rst=1;
Delay_ms(35000); //Gsm net search
Send_GSM();
Delay_ms(20000); //Time to send sms
SIM800_rst=0;
Delay_ms(100);
RF_EN=0;
LED_Stat=0;
LED_RFstat=0;
b=1;
}
ADXL345_Reset();
}
if(VbatCalc>20||Vbat<760){ //>300mv <11.9V
Delay_ms(10000);
Vbat=ADC_Read(1);
VbatOld=Vbat;
Vbat=ADC_Read(1);
VbatCalc=VbatOld-Vbat;
//doors opened
//stay in loop for 5min or as long as Vbat>14V
while((j<700)||(Vbat>895)){
LED_Stat=1;
Delay_ms(100);
LED_Stat=0;
Delay_ms(100);
j++;
}
//Reset INT1 output
ADXL345_Reset();
j=0;
}
}
void main(){
Init_main();
/* while(1){
LED_Stat=1;
LED_Stat=0;
}
*/
while(1){
prio_counter++;
Led();
Read_Vbat();
if(prio_counter==1500){
Read_ADXL345();
prio_counter=0;
}
}
}