void Show_SingleResistor(uint8_t ID1, uint8_t ID2) { Resistor_Type *Resistor; /* pointer to resistor */ Resistor = &Resistors[0]; /* pointer to first resistor */ /* show pinout */ LCD_Char(ID1); LCD_EEString(Resistor_str); LCD_Char(ID2); /* show resistance value */ LCD_Space(); DisplayValue(Resistor->Value, Resistor->Scale, LCD_CHAR_OMEGA); }
void Show_FET_Channel(void) { LCD_Space(); /* display space */ /* channel type */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel */ { LCD_Char('N'); } else /* p-channel */ { LCD_Char('P'); } LCD_EEString(Channel_str); /* display: -ch */ }
void Show_Error() { if (Check.Type == TYPE_DISCHARGE) /* discharge failed */ { LCD_EEString(DischargeFailed_str); /* display: Battery? */ /* display probe number and remaining voltage */ LCD_NextLine(); LCD_ProbeNumber(Check.Probe); LCD_Char(':'); LCD_Space(); DisplayValue(Check.U, -3, 'V'); } }
void Show_SemiPinout(uint8_t A, uint8_t B, uint8_t C) { uint8_t i, j; /* counter */ unsigned char Pin[3]; /* component pins */ unsigned char ID[3]; /* component pin IDs */ /* copy probe pin numbers */ Pin[0] = Semi.A; Pin[1] = Semi.B; Pin[2] = Semi.C; /* copy pin characters/IDs */ ID[0] = A; ID[1] = B; ID[2] = C; /* display: 123 */ for (i = 0; i <= 2; i++) { LCD_ProbeNumber(i); } /* display: = */ LCD_Char('='); /* display pin IDs */ for (i = 0; i <= 2; i++) /* loop through probe pins */ { for (j = 0; j <= 2; j++) /* loop through component pins */ { if (i == Pin[j]) /* probe pin matches */ { LCD_Char(ID[j]); /* show ID */ } } } }
void LCD_PrintValueI(u8 x, u8 y, u32 data) { u8 i,j,k,l,m; /*if(data < 0)////////////////////////////////////////////////////////////////////////////////有符号时用 { LCD_Char(x,y,'-'); data = - data; } else { LCD_Char(x,y,'+'); }*/ l = data/10000; m= (data%10000)/1000; i = (data%1000)/100; j = (data%100)/10; k = data%10; LCD_Char(x+6,y,l+48); LCD_Char(x+18,y,m+48); LCD_Char(x+30,y,i+48); LCD_Char(x+42,y,j+48); LCD_Char(x+54,y,k+48); }
void Show_Fail(void) { /* display info */ LCD_EEString(Failed1_str); /* display: No component */ LCD_NextLine_EEString(Failed2_str); /* display: found!*/ /* display numbers of diodes found */ if (Check.Diodes > 0) /* diodes found */ { LCD_Space(); /* display space */ LCD_Char(Check.Diodes + '0'); /* display number of diodes found */ LCD_Space(); /* display space */ LCD_EEString(Diode_AC_str); /* display: -|>|- */ } RunsMissed++; /* increase counter */ RunsPassed = 0; /* reset counter */ }
void Show_FET(void) { /* * Mapping for Semi structure: * A - Gate pin * B - Drain pin * C - Source pin * U_2 - V_th (mV) */ /* display type */ if (Check.Type & TYPE_MOSFET) /* MOSFET */ { LCD_EEString(MOS_str); /* display: MOS */ } else /* JFET */ { LCD_Char('J'); /* display: J */ } LCD_EEString(FET_str); /* display: FET */ /* display channel type */ Show_FET_Channel(); /* display mode for MOSFETs*/ if (Check.Type & TYPE_MOSFET) Show_FET_Mode(); /* pinout */ LCD_NextLine(); /* move to line #2 */ if (Check.Type & TYPE_SYMMETRICAL) /* symmetrical Drain and Source */ { /* we can't distinguish D and S */ Show_SemiPinout('G', 'x', 'x'); /* show pinout */ } else /* unsymmetrical Drain and Source */ { Show_SemiPinout('G', 'D', 'S'); /* show pinout */ } /* show diode, V_th and Cgs for MOSFETs */ if (Check.Type & TYPE_MOSFET) Show_FET_Extras(); }
size_t Nokia_lcd::write(uint8_t c) { byte fontWidth = pgm_read_byte(_font); if (c == '\n') { byte fontHeight = pgm_read_byte(_font+1); _y += fontHeight; _x = 0; return 0; } else if (c == '\r') { return 0; } if (_x > (131 - fontWidth)) return 0; LCD_Char(c, _x, _y, _color, _background, _font); _x += fontWidth; return 1; }
void Show_FlybackDiode(void) { LCD_Space(); /* display space */ /* first pin */ if (Check.Found == COMP_FET) /* FET */ { LCD_Char('D'); /* drain */ } else /* BJT/IGBT */ { LCD_Char('C'); /* collector */ } /* diode */ if (Check.Type & TYPE_N_CHANNEL) /* n-channel/NPN */ { /* * anode pointing to source/emitter * cathode pointing to drain/collector */ LCD_Char(LCD_CHAR_DIODE_CA); /* |<| */ } else /* p-channel/PNP */ { /* * anode pointing to drain/collector * cathode pointing to source/emitter */ LCD_Char(LCD_CHAR_DIODE_AC); /* |>| */ } /* second pin */ if (Check.Found == COMP_FET) /* FET */ { LCD_Char('S'); /* source */ } else /* BJT/IGBT */ { LCD_Char('E'); /* emitter */ } }
uint8_t SelfAdjust(void) { uint8_t Flag = 0; /* return value */ uint8_t Test = 1; /* test counter */ uint8_t Counter; /* loop counter */ uint8_t DisplayFlag; /* display flag */ uint16_t Val1 = 0, Val2 = 0, Val3 = 0; /* voltages */ uint8_t CapCounter = 0; /* number of C_Zero measurements */ uint16_t CapSum = 0; /* sum of C_Zero values */ uint8_t RCounter = 0; /* number of R_Zero measurements */ uint16_t RSum = 0; /* sum of R_Zero values */ uint8_t RiL_Counter = 0; /* number of U_RiL measurements */ uint16_t U_RiL = 0; /* sum of U_RiL values */ uint8_t RiH_Counter = 0; /* number of U_RiH measurements */ uint16_t U_RiH = 0; /* sum of U_RiL values */ uint32_t Val0; /* temp. value */ /* * measurements */ /* make sure all probes are shorted */ Counter = ShortCircuit(1); if (Counter == 0) Test = 10; /* skip adjustment on error */ while (Test <= 5) /* loop through tests */ { Counter = 1; /* repeat each measurement 5 times */ while (Counter <= 5) { /* display test number */ LCD_Clear(); LCD_Char('A'); /* display: a */ LCD_Char('0' + Test); /* display number */ LCD_Space(); DisplayFlag = 1; /* display values by default */ /* * tests */ switch (Test) { case 1: /* resistance of probe leads (probes shorted) */ LCD_EEString_Space(ROffset_str); /* display: R0 */ LCD_EEString(ProbeComb_str); /* display: 12 13 23 */ /* * The resistance is for two probes in series and we expect it to be * smaller than 1.00 Ohms, i.e. 0.50 Ohms for a single probe */ UpdateProbes(TP2, TP1, 0); Val1 = SmallResistor(0); if (Val1 < 100) /* within limit */ { RSum += Val1; RCounter++; } UpdateProbes(TP3, TP1, 0); Val2 = SmallResistor(0); if (Val2 < 100) /* whithin limit */ { RSum += Val2; RCounter++; } UpdateProbes(TP3, TP2, 0); Val3 = SmallResistor(0); if (Val3 < 100) /* within limit */ { RSum += Val3; RCounter++; } break; case 2: /* un-short probes */ ShortCircuit(0); /* make sure probes are not shorted */ Counter = 100; /* skip test */ DisplayFlag = 0; /* reset display flag */ break; case 3: /* internal resistance of MCU in pull-down mode */ LCD_EEString(RiLow_str); /* display: Ri- */ /* TP1: Gnd -- Ri -- probe -- Rl -- Ri -- Vcc */ ADC_PORT = 0; ADC_DDR = 1 << TP1; R_PORT = 1 << (TP1 * 2); R_DDR = 1 << (TP1 * 2); Val1 = ReadU_5ms(TP1); U_RiL += Val1; /* TP2: Gnd -- Ri -- probe -- Rl -- Ri -- Vcc */ ADC_DDR = 1 << TP2; R_PORT = 1 << (TP2 * 2); R_DDR = 1 << (TP2 * 2); Val2 = ReadU_5ms(TP2); U_RiL += Val2; /* TP3: Gnd -- Ri -- probe -- Rl -- Ri -- Vcc */ ADC_DDR = 1 << TP3; R_PORT = 1 << (TP3 * 2); R_DDR = 1 << (TP3 * 2); Val3 = ReadU_5ms(TP3); U_RiL += Val3; RiL_Counter += 3; break; case 4: /* internal resistance of MCU in pull-up mode */ LCD_EEString(RiHigh_str); /* display: Ri+ */ /* TP1: Gnd -- Ri -- Rl -- probe -- Ri -- Vcc */ R_PORT = 0; ADC_PORT = 1 << TP1; ADC_DDR = 1 << TP1; R_DDR = 1 << (TP1 * 2); Val1 = Config.Vcc - ReadU_5ms(TP1); U_RiH += Val1; /* TP2: Gnd -- Ri -- Rl -- probe -- Ri -- Vcc */ ADC_PORT = 1 << TP2; ADC_DDR = 1 << TP2; R_DDR = 1 << (TP2 * 2); Val2 = Config.Vcc - ReadU_5ms(TP2); U_RiH += Val2; /* TP3: Gnd -- Ri -- Rl -- probe -- Ri -- Vcc */ ADC_PORT = 1 << TP3; ADC_DDR = 1 << TP3; R_DDR = 1 << (TP3 * 2); Val3 = Config.Vcc - ReadU_5ms(TP3); U_RiH += Val3; RiH_Counter += 3; break; case 5: /* capacitance offset (PCB and probe leads) */ LCD_EEString_Space(CapOffset_str); /* display: C0 */ LCD_EEString(ProbeComb_str); /* display: 12 13 23 */ /* * The capacitance is for two probes and we expect it to be * less than 100pF. */ MeasureCap(TP2, TP1, 0); Val1 = (uint16_t)Caps[0].Raw; /* limit offset to 100pF */ if ((Caps[0].Scale == -12) && (Caps[0].Raw <= 100)) { CapSum += Val1; CapCounter++; } MeasureCap(TP3, TP1, 1); Val2 = (uint16_t)Caps[1].Raw; /* limit offset to 100pF */ if ((Caps[1].Scale == -12) && (Caps[1].Raw <= 100)) { CapSum += Val2; CapCounter++; } MeasureCap(TP3, TP2, 2); Val3 = (uint16_t)Caps[2].Raw; /* limit offset to 100pF */ if ((Caps[2].Scale == -12) && (Caps[2].Raw <= 100)) { CapSum += Val3; CapCounter++; } break; } /* reset ports to defaults */ ADC_DDR = 0; /* input mode */ ADC_PORT = 0; /* all pins low */ R_DDR = 0; /* input mode */ R_PORT = 0; /* all pins low */ /* display values */ if (DisplayFlag) { LCD_NextLine(); /* move to line #2 */ DisplayValue(Val1, 0 , 0); /* display TP1 */ LCD_Space(); DisplayValue(Val2, 0 , 0); /* display TP2 */ LCD_Space(); DisplayValue(Val3, 0 , 0); /* display TP3 */ } /* wait and check test push button */ if (Counter < 100) /* when we don't skip this test */ { DisplayFlag = TestKey(1000, 0); /* catch key press or timeout */ /* short press -> next test / long press -> end selftest */ if (DisplayFlag > 0) { Counter = 100; /* skip current test anyway */ if (DisplayFlag == 2) Test = 100; /* also skip selftest */ } } Counter++; /* next run */ } Test++; /* next one */ } /* * calculate values and offsets */ /* capacitance auto-zero: calculate average value for all probe pairs */ if (CapCounter == 15) { /* calculate average offset (pF) */ NV.CapZero = CapSum / CapCounter; Flag++; } /* resistance auto-zero: calculate average value for all probes pairs */ if (RCounter == 15) { /* calculate average offset (0.01 Ohms) */ NV.RZero = RSum / RCounter; Flag++; } /* RiL & RiH */ if ((RiL_Counter == 15) && (RiH_Counter == 15)) { /* * Calculate RiL and RiH using the voltage divider rule: * Ri = Rl * (U_Ri / U_Rl) * - scale up by 100, round up/down and scale down by 10 */ /* use values multiplied by 3 to increase accuracy */ U_RiL /= 5; /* average sum of 3 U_RiL */ U_RiH /= 5; /* average sum of 3 U_RiH */ Val1 = (Config.Vcc * 3) - U_RiL - U_RiH; /* U_Rl * 3 */ /* RiL */ Val0 = ((uint32_t)R_LOW * 100 * U_RiL) / Val1; /* Rl * U_Ri / U_Rl in 0.01 Ohm */ Val0 += 5; /* for automagic rounding */ Val0 /= 10; /* scale down to 0.1 Ohm */ if (Val0 < 250UL) /* < 25 Ohms */ { NV.RiL = (uint16_t)Val0; Flag++; } /* RiH */ Val0 = ((uint32_t)R_LOW * 100 * U_RiH) / Val1; /* Rl * U_Ri / U_Rl in 0.01 Ohm */ Val0 += 5; /* for automagic rounding */ Val0 /= 10; /* scale down to 0.1 Ohm */ if (Val0 < 280UL) /* < 29 Ohms */ { NV.RiH = (uint16_t)Val0; Flag++; } } /* show values and offsets */ ShowAdjust(); if (Flag == 4) Flag = 1; /* all adjustments done -> success */ else Flag = 0; /* signal error */ return Flag; }
/* main work function */ void work(void) { unsigned short i, j; unsigned char mailbox_num = 0; volatile ProtoIOMBox * mbox; /* setup status */ status_setup(); /* setup serial console */ usart1_setup(); /* setup proto */ proto_setup(); mbox = proto_srv_dat.mailboxes[mailbox_num]; /* setup button */ buttons_setup(); /* lcd setup */ LCD_Setup(); LCD_Clear(BLACK); for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { LCD_Pixel(j + 10, i + 10, test.data[i * 10 + j]); } } LCD_Window(0, 0, 9, 9); LCD_RS_LOW; LCD_SELECT; for (i = 0; i < 100; i++) { LCD_Send(test.data[i] >> 8); LCD_Send(test.data[i] & 0x00ff); } LCD_Cursor(0, 0); LCD_DESEL; /* check status */ check_status(); /* send ping */ mbox->outbox->header = 'C'; /* Command */ mbox->outbox->size = 0x00; /* 0 for ping request */ mbox->outbox_s = PROTO_IO_MBOX_READY; /* Box ready */ mbox->inbox->size = 64; /* buffer len for control */ mbox->inbox_s = PROTO_IO_MBOX_READY; /* Box ready */ /* wait connection estabilished */ while (status == 0); /* send ping message */ proto_send_msg(mailbox_num); /* wait to send message */ while (mbox->outbox_s <= PROTO_IO_MBOX_SEND); if (mbox->outbox_s == PROTO_IO_MBOX_COMPLETE) LCD_String("Con", 36, 6, 1, WHITE, GLASSY); else LCD_String("Un", 36, 6, 1, RED, GLASSY); /* get ping message */ /* FIXME wtf? this not work or work parity */ //proto_get_msg(mailbox_num); /* wait to get message */ while (mbox->inbox_s <= PROTO_IO_MBOX_SEND); if (mbox->inbox_s == PROTO_IO_MBOX_COMPLETE) { LCD_String("OK", 36 + 3 * 7, 6, 1, GREEN, GLASSY); for (i = 0; i < mbox->inbox->size; i++) LCD_Char(mbox->inbox->message[i], 70 + i * 6, 6, 1, WHITE, GLASSY); } else LCD_String("ERR", 36 + 3 * 7, 6, 1, RED, GLASSY); /* infinity loop */ while (1) { if (button_state.state[B_LGHT] == B_CLICK) { sender('+'); button_state.state[B_LGHT] = B_RELEASE; } if (button_state.state[B_MOD] == B_CLICK) { sender('m'); button_state.state[B_MOD] = B_RELEASE; } if (button_state.state[B_SET] == B_CLICK) { sender('-'); button_state.state[B_SET] = B_RELEASE; } if (button_state.state[B_UP] == B_CLICK) { sender('<'); button_state.state[B_UP] = B_RELEASE; } if (button_state.state[B_SU] == B_CLICK) { sender('p'); button_state.state[B_SU] = B_RELEASE; } if (button_state.state[B_DWN] == B_CLICK) { sender('>'); button_state.state[B_DWN] = B_RELEASE; } } }
void main() { DisableInterrupts; volatile u8 i; u32 bianliang; flash_init(); gpio_init (PORTA, 24, GPI_UP_PF,1);///////拨码 gpio_init (PORTA, 25, GPI_UP_PF,1); gpio_init (PORTA, 6, GPI_UP_PF,1); gpio_init (PORTA, 10, GPI_UP_PF,1);///////按键 gpio_init (PORTA, 12, GPI_UP_PF,1); gpio_init (PORTA, 8, GPI_UP_PF,1); if(gpio_get(PORTA,24)==1&&gpio_get(PORTA,25)==1&&gpio_get(PORTA,6)==0) { LCD_Init(); //flash_erase_sector(255); // flash_write(255,0x004,0x03e8);/////////////////////////////需要给定初值时 while(1&&tx==0) { if(gpio_get(PORTA,10)==0) { delayms(100); if(gpio_get(PORTA,10)==0)/////////确定按下加计数 { bianliang=flash_read(255,0x004,u32); delayms(50); bianliang+=5; flash_erase_sector(255); delayms(50); flash_write(255,0x004, (u32)bianliang); delayms(50); LCD_CLS(); LCD_PrintValueI(8, 4, bianliang); } } if(gpio_get(PORTA,12)==0) { delayms(100); if(gpio_get(PORTA,12)==0) { bianliang=flash_read(255,0x004,u32); delayms(50); bianliang-=5; flash_erase_sector(255); delayms(50); flash_write(255,0x004,(u32)bianliang); delayms(50); LCD_CLS();//清屏 LCD_PrintValueI(8, 4,bianliang); } } if(gpio_get(PORTA,8)==0) { delayms(100); if(gpio_get(PORTA,8)==0) { tx=1; } else tx=0; } } } /////////////////////////////////////////////////////////////////////////////////////////单道设置档 if(gpio_get(PORTA,24)==0&&gpio_get(PORTA,25)==1&&gpio_get(PORTA,6)==0)//////////////右转正值 { LCD_Init(); while(1) { if(gpio_get(PORTA,10)==0) { delayms(100); if(gpio_get(PORTA,10)==0)/////////单道右转 { delayms(50); flash_erase_sector(254); delayms(50); flash_write(254,0x004, (u32)6); delayms(50); LCD_Char( 10,3,'R'); LCD_Char(26 ,3,'+') ; LCD_Char(32 ,3,'6') ; } } if(gpio_get(PORTA,12)==0) { delayms(100); if(gpio_get(PORTA,12)==0)/////////单道左转 { delayms(50); flash_erase_sector(254); delayms(50); flash_write(254,0x004, (u32)(-6)); delayms(50); LCD_CLS(); LCD_Char( 10,3,'L'); LCD_Char(26 ,3,'-') ; LCD_Char(32 ,3,'6') ; } } if(gpio_get(PORTA,8)==0) { delayms(100); if(gpio_get(PORTA,8)==0)/////////单道直道 { delayms(50); flash_erase_sector(254); delayms(50); flash_write(254,0x004, (u32)0); delayms(50); LCD_CLS(); LCD_Char(32 ,3,'0'); } } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////速度档位 if(gpio_get(PORTA,24)==1&&gpio_get(PORTA,25)==1&&gpio_get(PORTA,6)==1)///////////////////// { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=8;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2200;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=33.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=32.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } if(gpio_get(PORTA,24)==0&&gpio_get(PORTA,25)==1&&gpio_get(PORTA,6)==1)///////////////////// { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=10;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2200;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=33.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=32.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } if(gpio_get(PORTA,24)==1&&gpio_get(PORTA,25)==0&&gpio_get(PORTA,6)==1)///////////////////// { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=12;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2200;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=33.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=32.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } if(gpio_get(PORTA,24)==0&&gpio_get(PORTA,25)==0&&gpio_get(PORTA,6)==1)//////////////////////最低速 1400 { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=14;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2200;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=33.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=32.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////特殊速度档 if(gpio_get(PORTA,24)==0&&gpio_get(PORTA,25)==0&&gpio_get(PORTA,6)==0) { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=14;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2400;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=31.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=30.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } if(gpio_get(PORTA,24)==1&&gpio_get(PORTA,25)==0&&gpio_get(PORTA,6)==0)//////////////////////////有值太大 { yz=10,yz1=6,yz2=3;///定义搜线阈值 buxianL=25,buxianR=27;//左右补线值 dandao=(int)flash_read(254,0x004,u32); zhijiao=16;//直角延时场数 quanheiMAX=60;//全黑最大值 quanbaiMIN=80;//全白最小值 dandaoBDD=9.455;//////////////////////////////////////////////////////////// dandaoHDD=9.455;//////////////////////////////////////////////////////////// zhijiaoBDpwmmax=500.0; zhijiaoBS_Kp=10.0; zhijiaoBD_Kp=378.25; zhijiaoHDpwmmax=300.0; zhijiaoHS_Kp=42.0;//50轻微振荡 zhijiaoHD_Kp=305.25;//299.25 zkp=2400;//清华PD:2053 卡尔曼PD:2200 zkd=47;//44/////////////50 S_Kpstart=10.0;// 1.3 S_Kistart=31.91;//11.8 S_Kpend=42.0;///////////////29.0 S_Kiend=30.01;//11.8 Sqiwang =1400;// 1.3 Sjishu =7;//11.8 D_Kp =305.25; //299.25 D_Kd =300.0;// D_Kdd=9.455;//12.05 zhangaiDmax=300.0; direction_pwmmax=300.0; } /**/ //串口初始化 asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); if(tx==1) uart_init(UART5,115200); else uart_init(UART5,9600); asm("nop"); asm("nop"); //CCD及其各引脚初始化 CCD1_init() ; CCD2_init() ; asm("nop"); asm("nop"); //PWM输出初始化 FTM_PWM_init(FTM0, CH0, 10000, 0); //R后退 FTM_PWM_init(FTM0, CH1, 10000, 0); //R前进 FTM_PWM_init(FTM0, CH2, 10000, 0); //L后退 FTM_PWM_init(FTM0, CH3, 10000, 0); //L前进 //拨码初始化 // gpio_init (PORTA, 7, GPI_UP_PF,1); asm("nop"); asm("nop"); gpio_init (PORTE, 1, GPI,0); gpio_init (PORTD, 15, GPI,0); gpio_init (PORTD, 14, GPI,0); gpio_init (PORTD, 12,GPI,0); asm("nop"); asm("nop"); asm("nop"); asm("nop"); //正交解码初始化 FTM1_QUAD_Iint(); FTM2_QUAD_Iint(); asm("nop"); asm("nop"); asm("nop"); asm("nop"); //各种中断初始化 pit_init_ms(PIT0, 1); asm("nop"); asm("nop"); asm("nop"); asm("nop"); // 陀螺仪及加速度计初始化 adc_init(ADC0, AD12); ////// PTB2 ENC adc_init(ADC0, AD12); ///PTB3 Z adc_init(ADC0, AD17); ///PTE24 DIR_ENC /////////////////////////////////////////////////陀螺仪开机自检 delayms(1000); gpio_init (PORTA, 17, GPO, 0); MMA7361level=flash_read(255,0x004,u32); rectifyT = ad_ave(ADC0,SE12,ADC_12bit,10); gyro_DIR=ad_ave(ADC0,SE17,ADC_12bit,10); // gyro_DIR=gyro_DIR/20; ///////////////////////////////////////////////// // gpio_init (PORTC, 0, GPI,0);不知道要用否 delayms(1500); EnableInterrupts; while(1) { if((gpio_get(PORTD,12)==0)&&(gpio_get(PORTD,14)==0))//||(gpio_get(PORTE,1)==1) {b=1;d=0;} if(fs>=1) { DisableInterrupts; fs=0;js=0; ImageCapture1(Pixel1); ImageCapture2(Pixel2); EnableInterrupts; Analyze_CCD_Data(); } if(tx==1) { sendDataToCCDViewer(0,Pixel1);////////////////////////////////////// sendDataToCCDViewer(1,Pixel2); sendDataToScope(); } else { OutData[0]=Min_Data1;//L_Max_Data_Place3 OutData[1]=Max_Data1;//R_Max_Data_Place1 OutData[2]=L_Max_Data_Place1; //L_Max_Data_Place1 OutData[3]=R_Max_Data_Place1;// OutPut_Data(); }// //sb[0]=FTM1_CNT; //sb[1]=MMA7361; // tongxun(); } }
void Nokia_lcd::cLCD_Char(char c, unsigned char x, unsigned char y, int fColor, int bColor) { LCD_Char(c, y,x, fColor, bColor); }
void LCD_PrintValueFP(u8 x, u8 y, u8 data, u8 num) { u8 m,i,j,k; LCD_Char(x, y, '.'); m= data/1000; i = (data%1000)/100; j = (data%100)/10; k = data%10; switch(num) { case 1: LCD_Char(x+6,y,k+48); break; case 2: LCD_Char(x+6,y,j+48); LCD_Char(x+12,y,k+48); break; case 3: LCD_Char(x+6,y,i+48); LCD_Char(x+12,y,j+48); LCD_Char(x+18,y,k+48); break; case 4: LCD_Char(x+6,y,m+48); LCD_Char(x+12,y,i+48); LCD_Char(x+18,y,j+48); LCD_Char(x+24,y,k+48); break; } }
int main(void) { uint16_t U_Bat; /* voltage of power supply */ uint8_t Test; /* test value */ /* * init */ /* switch on power to keep me alive */ CONTROL_DDR = (1 << POWER_CTRL); /* set pin as output */ CONTROL_PORT = (1 << POWER_CTRL); /* set pin to drive power management transistor */ /* setup MCU */ MCUCR = (1 << PUD); /* disable pull-up resistors globally */ ADCSRA = (1 << ADEN) | ADC_CLOCK_DIV; /* enable ADC and set clock divider */ #ifdef HW_RELAY /* init relay (safe mode) */ /* ADC_PORT should be 0 */ ADC_DDR = (1 << TP_REF); /* short circuit probes */ #endif /* catch watchdog */ Test = (MCUSR & (1 << WDRF)); /* save watchdog flag */ MCUSR &= ~(1 << WDRF); /* reset watchdog flag */ wdt_disable(); /* disable watchdog */ /* init LCD module */ LCD_BusSetup(); /* setup bus */ LCD_Init(); /* initialize LCD */ LCD_NextLine_Mode(MODE_NONE); /* reset line mode */ /* * watchdog was triggered (timeout 2s) * - This is after the MCU done a reset driven by the watchdog. * - Does only work if the capacitor at the base of the power management * transistor is large enough to survive a MCU reset. Otherwise the * tester simply loses power. */ if (Test) { LCD_Clear(); /* display was initialized before */ LCD_EEString(Timeout_str); /* display: timeout */ LCD_NextLine_EEString(Error_str); /* display: error */ MilliSleep(2000); /* give user some time to read */ CONTROL_PORT = 0; /* power off myself */ return 0; /* exit program */ } /* * operation mode selection */ Config.SleepMode = SLEEP_MODE_PWR_SAVE; /* default: power save */ UI.TesterMode = MODE_CONTINOUS; /* set default mode: continous */ Test = 0; /* key press */ /* catch long key press */ if (!(CONTROL_PIN & (1 << TEST_BUTTON))) /* if test button is pressed */ { RunsMissed = 0; while (Test == 0) { MilliSleep(20); if (!(CONTROL_PIN & (1 << TEST_BUTTON))) /* if button is still pressed */ { RunsMissed++; if (RunsMissed > 100) Test = 3; /* >2000ms */ } else /* button released */ { Test = 1; /* <300ms */ if (RunsMissed > 15) Test = 2; /* >300ms */ } } } /* key press >300ms sets autohold mode */ if (Test > 1) UI.TesterMode = MODE_AUTOHOLD; /* * load saved offsets and values */ if (Test == 3) /* key press >2s resets to defaults */ { SetAdjustDefaults(); /* set default values */ } else /* normal mode */ { LoadAdjust(); /* load adjustment values */ } /* set extra stuff */ #ifdef SW_CONTRAST LCD_Contrast(NV.Contrast); /* set LCD contrast */ #endif /* * welcome user */ LCD_EEString(Tester_str); /* display: Component Tester */ LCD_NextLine_EEString_Space(Edition_str); /* display firmware edition */ LCD_EEString(Version_str); /* display firmware version */ MilliSleep(1500); /* let the user read the display */ /* * init variables */ /* cycling */ RunsMissed = 0; RunsPassed = 0; /* default offsets and values */ Config.Samples = ADC_SAMPLES; /* number of ADC samples */ Config.AutoScale = 1; /* enable ADC auto scaling */ Config.RefFlag = 1; /* no ADC reference set yet */ Config.Vcc = UREF_VCC; /* voltage of Vcc */ wdt_enable(WDTO_2S); /* enable watchdog (timeout 2s) */ /* * main processing cycle */ start: /* reset variabels */ Check.Found = COMP_NONE; Check.Type = 0; Check.Done = 0; Check.Diodes = 0; Check.Resistors = 0; Semi.U_1 = 0; Semi.I_1 = 0; Semi.F_1 = 0; /* reset hardware */ ADC_DDR = 0; /* set all pins of ADC port as input */ /* also remove short circuit by relay */ LCD_NextLine_Mode(MODE_KEEP); /* line mode: keep first line */ LCD_Clear(); /* clear LCD */ /* * voltage reference */ #ifdef HW_REF25 /* external 2.5V reference */ Config.Samples = 200; /* do a lot of samples for high accuracy */ U_Bat = ReadU(TP_REF); /* read voltage of reference (mV) */ Config.Samples = ADC_SAMPLES; /* set samples back to default */ if ((U_Bat > 2250) && (U_Bat < 2750)) /* check for valid reference */ { uint32_t Temp; /* adjust Vcc (assuming 2.495V typically) */ Temp = ((uint32_t)Config.Vcc * UREF_25) / U_Bat; Config.Vcc = (uint16_t)Temp; } #endif /* internal bandgap reference */ Config.Bandgap = ReadU(0x0e); /* dummy read for bandgap stabilization */ Config.Samples = 200; /* do a lot of samples for high accuracy */ Config.Bandgap = ReadU(0x0e); /* get voltage of bandgap reference (mV) */ Config.Samples = ADC_SAMPLES; /* set samples back to default */ Config.Bandgap += NV.RefOffset; /* add voltage offset */ /* * battery check */ /* * ADC pin is connected to a voltage divider Rh = 10k and Rl = 3k3. * Ul = (Uin / (Rh + Rl)) * Rl -> Uin = (Ul * (Rh + Rl)) / Rl * Uin = (Ul * (10k + 3k3)) / 3k3 = 4 * Ul */ /* get current voltage */ U_Bat = ReadU(TP_BAT); /* read voltage (mV) */ U_Bat *= 4; /* calculate U_bat (mV) */ U_Bat += BAT_OFFSET; /* add offset for voltage drop */ /* display battery voltage */ LCD_EEString_Space(Battery_str); /* display: Bat. */ DisplayValue(U_Bat / 10, -2, 'V'); /* display battery voltage */ LCD_Space(); /* check limits */ if (U_Bat < BAT_POOR) /* low level reached */ { LCD_EEString(Low_str); /* display: low */ MilliSleep(2000); /* let user read info */ goto power_off; /* power off */ } else if (U_Bat < BAT_POOR + 1000) /* warning level reached */ { LCD_EEString(Weak_str); /* display: weak */ } else /* ok */ { LCD_EEString(OK_str); /* display: ok */ } /* * probing */ /* display start of probing */ LCD_NextLine_EEString(Running_str); /* display: probing... */ /* try to discharge any connected component */ DischargeProbes(); if (Check.Found == COMP_ERROR) /* discharge failed */ { goto result; /* skip all other checks */ } /* enter main menu if requested by short-circuiting all probes */ if (AllProbesShorted() == 3) { MainMenu(); /* enter mainmenu */; goto end; /* new cycle after job is is done */ } /* check all 6 combinations of the 3 probes */ CheckProbes(TP1, TP2, TP3); CheckProbes(TP2, TP1, TP3); CheckProbes(TP1, TP3, TP2); CheckProbes(TP3, TP1, TP2); CheckProbes(TP2, TP3, TP1); CheckProbes(TP3, TP2, TP1); /* if component might be a capacitor */ if ((Check.Found == COMP_NONE) || (Check.Found == COMP_RESISTOR)) { /* tell user to be patient with large caps :-) */ LCD_Space(); LCD_Char('C'); /* check all possible combinations */ MeasureCap(TP3, TP1, 0); MeasureCap(TP3, TP2, 1); MeasureCap(TP2, TP1, 2); } /* * output test results */ result: LCD_Clear(); /* clear LCD */ LCD_NextLine_Mode(MODE_KEEP | MODE_KEY); /* call output function based on component type */ switch (Check.Found) { case COMP_ERROR: Show_Error(); goto end; break; case COMP_DIODE: Show_Diode(); break; case COMP_BJT: Show_BJT(); break; case COMP_FET: Show_FET(); break; case COMP_IGBT: Show_IGBT(); break; case COMP_THYRISTOR: Show_Special(); break; case COMP_TRIAC: Show_Special(); break; case COMP_RESISTOR: Show_Resistor(); break; case COMP_CAPACITOR: Show_Capacitor(); break; default: /* no component found */ Show_Fail(); goto end; } /* component was found */ RunsMissed = 0; /* reset counter */ RunsPassed++; /* increase counter */ /* * take care about cycling and power-off */ end: #ifdef HW_RELAY ADC_DDR = (1<<TP_REF); /* short circuit probes */ #endif LCD_NextLine_Mode(MODE_NONE); /* reset next line mode */ /* get key press or timeout */ Test = TestKey((uint16_t)CYCLE_DELAY, 12); if (Test == 0) /* timeout (no key press) */ { /* check if we reached the maximum number of rounds (continious mode only) */ if ((RunsMissed >= CYCLE_MAX) || (RunsPassed >= CYCLE_MAX * 2)) { goto power_off; /* -> power off */ } } else if (Test == 1) /* short key press */ { /* a second key press triggers extra functions */ MilliSleep(50); Test = TestKey(300, 0); if (Test > 0) /* short or long key press */ { #ifdef HW_RELAY ADC_DDR = 0; /* remove short circuit */ #endif MainMenu(); /* enter main menu */ goto end; /* re-run cycle control */ } } else if (Test == 2) /* long key press */ { goto power_off; /* -> power off */ } #ifdef HW_ENCODER else if (Test == 4) /* rotary encoder: left turn */ { MainMenu(); /* enter main menu */ goto end; /* re-run cycle control */ } #endif /* default action (also for rotary encoder) */ goto start; /* -> next round */ power_off: /* display feedback (otherwise the user will wait :-) */ LCD_Clear(); LCD_EEString(Bye_str); wdt_disable(); /* disable watchdog */ CONTROL_PORT &= ~(1 << POWER_CTRL); /* power off myself */ return 0; }
//============================================================== //函数名: void LED_PrintValueF(uchar x, uchar y, float data, uchar num); //功能描述:将一个float型数转换成整数部分5位带小数和符号的数据并进行显示 //参数:x的范围为0~62,y为页的范围0~7,data为需要转化显示的数值整数部分最多位5位 num表示保留的小数位0~4 //返回:无 //num小数位数最多四位 //============================================================== void LCD_PrintValueF(u8 x, u8 y, float data, u8 num) { u8 l,m,i,j,k; //万千百十个 u8 databiti = 6; //整数位数 u8 tempdataui = 0; int tempdataii = (int)data; //整数部分 long int tempdatalp = (long int)((data - (int)data)*10000); //取小数位后4位 //整数部分显示 if(data < 0.0000001) LCD_Char(x, y,'-'); else LCD_Char(x, y,'+'); if(tempdataii < 0)tempdataii = - tempdataii; //去掉整数部分负号 tempdataui = tempdataii; l = tempdataui/10000; m= (tempdataui%10000)/1000; i = (tempdataui%1000)/100; j = (tempdataui%100)/10; k = tempdataui%10; if (l != 0) //五位 { LCD_Char(x+6,y,l+48); LCD_Char(x+12,y,m+48); LCD_Char(x+18,y,i+48); LCD_Char(x+24,y,j+48); LCD_Char(x+30,y,k+48); } else if(m != 0) //四位 { databiti = 5; LCD_Char(x+6,y,m+48); LCD_Char(x+12,y,i+48); LCD_Char(x+18,y,j+48); LCD_Char(x+24,y,k+48); } else if(i != 0) //三位 { databiti = 4; LCD_Char(x+6,y,i+48); LCD_Char(x+12,y,j+48); LCD_Char(x+18,y,k+48); } else if(j != 0) //两位 { databiti = 3; LCD_Char(x+6,y,j+48); LCD_Char(x+12,y,k+48); } else { databiti = 2; LCD_Char(x+6,y,k+48); } if(tempdatalp < 0)tempdatalp = - tempdatalp; //去掉小数部分负号 switch(num) { case 0: break; case 1: LCD_PrintValueFP(x + databiti * 6, y, (unsigned int)(tempdatalp / 1000),num);break; case 2: LCD_PrintValueFP(x + databiti * 6, y, (unsigned int)(tempdatalp / 100),num);break; case 3: LCD_PrintValueFP(x + databiti * 6, y, (unsigned int)(tempdatalp / 10),num);break; case 4: LCD_PrintValueFP(x + databiti * 6, y, (unsigned int)(tempdatalp),num);break; } }
void Show_Diode(void) { Diode_Type *D1; /* pointer to diode #1 */ Diode_Type *D2 = NULL; /* pointer to diode #2 */ uint8_t CapFlag = 1; /* flag for capacitance output */ uint8_t A = 5; /* ID of common anode */ uint8_t C = 5; /* ID of common cothode */ uint8_t R_Pin1 = 5; /* B_E resistor's pin #1 */ uint8_t R_Pin2 = 5; /* B_E resistor's pin #2 */ uint16_t I_leak; /* leakage current */ D1 = &Diodes[0]; /* pointer to first diode */ /* * figure out which diodes to display */ if (Check.Diodes == 1) /* single diode */ { C = D1->C; /* make anode first pin */ } else if (Check.Diodes == 2) /* two diodes */ { D2 = D1; D2++; /* pointer to second diode */ if (D1->A == D2->A) /* common anode */ { A = D1->A; /* save common anode */ /* possible PNP BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->C; R_Pin2 = D2->C; } else if (D1->C == D2->C) /* common cathode */ { C = D1->C; /* save common cathode */ /* possible NPN BJT with low value B-E resistor and flyback diode */ R_Pin1 = D1->A; R_Pin2 = D2->A; } else if ((D1->A == D2->C) && (D1->C == D2->A)) /* anti-parallel */ { A = D1->A; /* anode and cathode */ C = A; /* are the same */ CapFlag = 0; /* skip capacitance */ } } else if (Check.Diodes == 3) /* three diodes */ { uint8_t n; uint8_t m; /* * Two diodes in series are additionally detected as third big diode: * - Check for any possible way of 2 diodes be connected in series. * - Only once the cathode of diode #1 matches the anode of diode #2. */ for (n = 0; n <= 2; n++) /* loop for first diode */ { D1 = &Diodes[n]; /* get pointer of first diode */ for (m = 0; m <= 2; m++) /* loop for second diode */ { D2 = &Diodes[m]; /* get pointer of second diode */ if (n != m) /* don't check same diode :-) */ { if (D1->C == D2->A) /* got match */ { n = 5; /* end loops */ m = 5; } } } } if (n < 5) D2 = NULL; /* no match found */ C = D1->C; /* cathode of first diode */ A = 3; /* in series mode */ } else /* to much diodes */ { D1 = NULL; /* don't display any diode */ Show_Fail(); /* and tell user */ return; } /* * display pins */ /* first Diode */ if (A < 3) LCD_ProbeNumber(D1->C); /* common anode */ else LCD_ProbeNumber(D1->A); /* common cathode */ if (A < 3) LCD_EEString(Diode_CA_str); /* common anode */ else LCD_EEString(Diode_AC_str); /* common cathode */ if (A < 3) LCD_ProbeNumber(A); /* common anode */ else LCD_ProbeNumber(C); /* common cathode */ if (D2) /* second diode */ { if (A <= 3) LCD_EEString(Diode_AC_str); /* common anode or in series */ else LCD_EEString(Diode_CA_str); /* common cathode */ if (A == C) LCD_ProbeNumber(D2->A); /* anti parallel */ else if (A <= 3) LCD_ProbeNumber(D2->C); /* common anode or in series */ else LCD_ProbeNumber(D2->A); /* common cathode */ } /* check for B-E resistor for possible BJT */ if (R_Pin1 < 5) /* possible BJT */ { if (CheckSingleResistor(R_Pin1, R_Pin2) == 1) /* found B-E resistor */ { /* show: PNP/NPN? */ LCD_Space(); if (A < 3) LCD_EEString(PNP_str); else LCD_EEString(NPN_str); LCD_Char('?'); LCD_NextLine(); /* go to line #2 */ R_Pin1 += '1'; /* convert to character */ R_Pin2 += '1'; Show_SingleResistor(R_Pin1, R_Pin2); /* show resistor */ CapFlag = 0; /* skip capacitance */ } } /* * display: * - Uf (forward voltage) * - reverse leakage current (for single diodes) * - capacitance (not for anti-parallel diodes) */ /* display Uf */ LCD_NextLine_EEString_Space(Vf_str); /* display: Vf */ /* first diode */ DisplayValue(D1->V_f, -3, 'V'); LCD_Space(); /* display low current Uf and reverse leakage current for a single diode */ if (D2 == NULL) /* single diode */ { /* display low current Uf if it's quite low (Ge/Schottky diode) */ if (D1->V_f2 < 250) { LCD_Char('('); DisplayValue(D1->V_f2, 0, 0); LCD_Char(')'); } /* reverse leakage current */ UpdateProbes(D1->C, D1->A, 0); /* reverse diode */ I_leak = GetLeakageCurrent(); /* get current (in µA) */ if (I_leak > 0) /* show if not zero */ { LCD_NextLine_EEString_Space(I_R_str); /* display: I_R */ DisplayValue(I_leak, -6, 'A'); /* display current */ } } else /* two diodes */ { /* show Uf of second diode */ DisplayValue(D2->V_f, -3, 'V'); } /* display capacitance */ if (CapFlag == 1) /* if requested */ { LCD_NextLine_EEString_Space(DiodeCap_str); /* display: C */ Show_Diode_Cap(D1); /* first diode */ LCD_Space(); Show_Diode_Cap(D2); /* second diode (optional) */ } }
void Show_BJT(void) { Diode_Type *Diode; /* pointer to diode */ unsigned char *String; /* display string pointer */ uint8_t Counter; /* counter */ uint8_t A_Pin; /* pin acting as anode */ uint8_t C_Pin; /* pin acting as cathode */ uint16_t V_BE; /* V_BE */ int16_t Slope; /* slope of forward voltage */ /* * Mapping for Semi structure: * A - Base pin * B - Collector pin * C - Emitter pin * U_1 - U_BE (mV) * I_1 - I_CE0 (µA) * F_1 - hFE */ /* preset stuff based on BJT type */ if (Check.Type & TYPE_NPN) /* NPN */ { String = (unsigned char *)NPN_str; /* "NPN" */ /* direction of B-E diode: B -> E */ A_Pin = Semi.A; /* anode at base */ C_Pin = Semi.C; /* cathode at emitter */ } else /* PNP */ { String = (unsigned char *)PNP_str; /* "PNP" */ /* direction of B-E diode: E -> B */ A_Pin = Semi.C; /* anode at emitter */ C_Pin = Semi.A; /* cathode at base */ } /* display type */ LCD_EEString_Space(BJT_str); /* display: BJT */ LCD_EEString(String); /* display: NPN / PNP */ /* parasitic BJT (freewheeling diode on same substrate) */ if (Check.Type & TYPE_PARASITIC) { LCD_Char('+'); } LCD_NextLine(); /* move to line #2 */ /* display pinout */ Show_SemiPinout('B', 'C', 'E'); /* optional freewheeling diode */ if (Check.Diodes > 2) /* transistor is a set of two diodes :-) */ { Show_FlybackDiode(); /* show diode */ } LCD_NextLine(); /* next line */ /* display either optional B-E resistor or hFE & V_BE */ if (CheckSingleResistor(C_Pin, A_Pin) == 1) /* found B-E resistor */ { Show_SingleResistor('B', 'E'); } else /* no B-E resistor found */ { /* hFE and V_BE */ /* display hFE */ LCD_EEString_Space(hFE_str); /* display: h_FE */ DisplayValue(Semi.F_1, 0, 0); /* display V_BE (taken from diode forward voltage) */ Diode = &Diodes[0]; /* get pointer of first diode */ Counter = 0; while (Counter < Check.Diodes) /* check all diodes */ { /* if the diode matches the transistor's B-E diode */ if ((Diode->A == A_Pin) && (Diode->C == C_Pin)) { LCD_NextLine_EEString_Space(V_BE_str); /* display: V_BE */ /* * Vf is quite linear for a logarithmicly scaled I_b. * So we may interpolate the Vf values of low and high test current * measurements for a virtual test current. Low test current is 10µA * and high test current is 7mA. That's a logarithmic scale of * 3 decades. */ /* calculate slope for one decade */ Slope = Diode->V_f - Diode->V_f2; Slope /= 3; /* select V_BE based on hFE */ if (Semi.F_1 < 100) /* low hFE */ { /* * BJTs with low hFE are power transistors and need a large I_b * to drive the load. So we simply take Vf of the high test current * measurement (7mA). */ V_BE = Diode->V_f; } else if (Semi.F_1 < 250) /* mid-range hFE */ { /* * BJTs with a mid-range hFE are signal transistors and need * a small I_b to drive the load. So we interpolate Vf for * a virtual test current of about 1mA. */ V_BE = Diode->V_f - Slope; } else /* high hFE */ { /* * BJTs with a high hFE are small signal transistors and need * only a very small I_b to drive the load. So we interpolate Vf * for a virtual test current of about 0.1mA. */ V_BE = Diode->V_f2 + Slope; } DisplayValue(V_BE, -3, 'V'); Counter = 10; /* end loop */ } else /* diode doesn't match */ { Counter++; /* increase counter */ Diode++; /* next one */ } } } /* I_CEO: collector emitter cutoff current (leakage) */ if (Semi.I_1 > 0) /* show if not zero */ { LCD_NextLine_EEString_Space(I_CEO_str); /* display: I_CE0 */ DisplayValue(Semi.I_1, -6, 'A'); /* display current */ } }
uint8_t SelfTest(void) { uint8_t Flag = 0; /* return value */ uint8_t Test = 1; /* test counter */ uint8_t Counter; /* loop counter */ uint8_t DisplayFlag; /* display flag */ uint16_t Val0; /* voltage/value */ int16_t Val1 = 0, Val2 = 0, Val3 = 0; /* voltages/values */ /* make sure all probes are shorted */ Counter = ShortCircuit(1); if (Counter == 0) Test = 10; /* skip selftest */ /* loop through all tests */ while (Test <= 6) { Counter = 1; /* repeat each test 5 times */ while (Counter <= 5) { /* display test number */ LCD_Clear(); LCD_Char('T'); /* display: T */ LCD_Char('0' + Test); /* display test number */ LCD_Space(); DisplayFlag = 1; /* display values by default */ /* * tests */ switch (Test) { case 1: /* reference voltage */ Val0 = ReadU(0x0e); /* dummy read for bandgap stabilization */ Val0 = ReadU(0x0e); /* read bandgap reference voltage */ LCD_EEString(URef_str); /* display: Vref */ LCD_NextLine(); DisplayValue(Val0, -3, 'V'); /* display voltage in mV */ DisplayFlag = 0; /* reset flag */ break; case 2: /* compare Rl resistors (probes still shorted) */ LCD_EEString_Space(Rl_str); /* display: +Rl- */ LCD_EEString(ProbeComb_str); /* display: 12 13 23 */ /* set up a voltage divider with the Rl's */ /* substract theoretical voltage of voltage divider */ /* TP1: Gnd -- Rl -- probe-2 -- probe-1 -- Rl -- Vcc */ R_PORT = 1 << (TP1 * 2); R_DDR = (1 << (TP1 * 2)) | (1 << (TP2 * 2)); Val1 = ReadU_20ms(TP3); Val1 -= ((int32_t)Config.Vcc * (R_MCU_LOW + R_LOW)) / (R_MCU_LOW + R_LOW + R_LOW + R_MCU_HIGH); /* TP1: Gnd -- Rl -- probe-3 -- probe-1 -- Rl -- Vcc */ R_DDR = (1 << (TP1 * 2)) | (1 << (TP3 * 2)); Val2 = ReadU_20ms(TP2); Val2 -= ((int32_t)Config.Vcc * (R_MCU_LOW + R_LOW)) / (R_MCU_LOW + R_LOW + R_LOW + R_MCU_HIGH); /* TP1: Gnd -- Rl -- probe-3 -- probe-2 -- Rl -- Vcc */ R_PORT = 1 << (TP2 * 2); R_DDR = (1 << (TP2 * 2)) | (1 << (TP3 * 2)); Val3 = ReadU_20ms(TP2); Val3 -= ((int32_t)Config.Vcc * (R_MCU_LOW + R_LOW)) / (R_MCU_LOW + R_LOW + R_LOW + R_MCU_HIGH); break; case 3: /* compare Rh resistors (probes still shorted) */ LCD_EEString_Space(Rh_str); /* display: +Rh- */ LCD_EEString(ProbeComb_str); /* display: 12 13 23 */ /* set up a voltage divider with the Rh's */ /* TP1: Gnd -- Rh -- probe-2 -- probe-1 -- Rh -- Vcc */ R_PORT = 2 << (TP1 * 2); R_DDR = (2 << (TP1 * 2)) | (2 << (TP2 * 2)); Val1 = ReadU_20ms(TP3); Val1 -= (Config.Vcc / 2); /* TP1: Gnd -- Rh -- probe-3 -- probe-1 -- Rh -- Vcc */ R_DDR = (2 << (TP1 * 2)) | (2 << (TP3 * 2)); Val2 = ReadU_20ms(TP2); Val2 -= (Config.Vcc / 2); /* TP1: Gnd -- Rh -- probe-3 -- probe-2 -- Rh -- Vcc */ R_PORT = 2 << (TP2 * 2); R_DDR = (2 << (TP2 * 2)) | (2 << (TP3 * 2)); Val3 = ReadU_20ms(TP1); Val3 -= (Config.Vcc / 2); break; case 4: /* un-short probes */ ShortCircuit(0); /* make sure probes are not shorted */ Counter = 100; /* skip test */ DisplayFlag = 0; /* reset flag */ break; case 5: /* Rh resistors pulled down */ LCD_EEString(RhLow_str); /* display: Rh- */ /* TP1: Gnd -- Rh -- probe */ R_PORT = 0; R_DDR = 2 << (TP1 * 2); Val1 = ReadU_20ms(TP1); /* TP1: Gnd -- Rh -- probe */ R_DDR = 2 << (TP2 * 2); Val2 = ReadU_20ms(TP2); /* TP1: Gnd -- Rh -- probe */ R_DDR = 2 << (TP3 * 2); Val3 = ReadU_20ms(TP3); break; case 6: /* Rh resistors pulled up */ LCD_EEString(RhHigh_str); /* display: Rh+ */ /* TP1: probe -- Rh -- Vcc */ R_DDR = 2 << (TP1 * 2); R_PORT = 2 << (TP1 * 2); Val1 = ReadU_20ms(TP1); /* TP1: probe -- Rh -- Vcc */ R_DDR = 2 << (TP2 * 2); R_PORT = 2 << (TP2 * 2); Val2 = ReadU_20ms(TP2); /* TP1: probe -- Rh -- Vcc */ R_DDR = 2 << (TP3 * 2); R_PORT = 2 << (TP3 * 2); Val3 = ReadU_20ms(TP3); break; } /* reset ports to defaults */ R_DDR = 0; /* input mode */ R_PORT = 0; /* all pins low */ /* display voltages/values of all probes */ if (DisplayFlag) { LCD_NextLine(); /* move to line #2 */ DisplaySignedValue(Val1, 0 , 0); /* display TP1 */ LCD_Space(); DisplaySignedValue(Val2, 0 , 0); /* display TP2 */ LCD_Space(); DisplaySignedValue(Val3, 0 , 0); /* display TP3 */ } /* wait and check test push button */ if (Counter < 100) /* when we don't skip this test */ { DisplayFlag = TestKey(1000, 0); /* catch key press or timeout */ /* short press -> next test / long press -> end selftest */ if (DisplayFlag > 0) { Counter = 100; /* skip current test anyway */ if (DisplayFlag == 2) Test = 100; /* also skip selftest */ } } Counter++; /* next run */ } Test++; /* next one */ } Flag = 1; /* signal success */ return Flag; }