?? ddcp.c
字號(hào):
/********************************************** vim: set sw=8 ts=8 si :* Author: Guido Socher, Copyright: GPL * This is the main program for the digital dc power supply* * See http://www.tuxgraphics.org/electronics/* * Chip type : ATMEGA8* Clock frequency : Internal clock 4 Mhz *********************************************/#include <avr/io.h>#include <inttypes.h>#include <avr/interrupt.h>#include "lcd.h"#include "dac.h"#include "kbd.h"#include "analog.h"#include "avr_compat.h"#include "hardware_settings.h"#include <stdlib.h> // atoi#include <string.h> #include <avr/eeprom.h> static int set_val[2];// the set values but converted to ADC stepsstatic int set_val_adcUnits[2]; void delay_ms(unsigned char ms)/* delay for a minimum of <ms> *//* with a 4Mhz clock */{ uint8_t inner,inner1; while (ms) { inner = 200; while (inner) { inner--; inner1 = 70; while (inner1) { inner1--; } } ms--; }}// Convert a integer which is representing a float into a string.// decimalpoint_pos sets the decimal point after 2 pos: e.g 74 becomes "0.74"// The integer may not be larger than 10000.// The integer must be a positive number.// spacepadd can be used to add a leading speace if number is less than 10static void int_to_ascii(int inum,char *outbuf,signed char decimalpoint_pos,signed char spacepadd){ signed char i,j; char chbuf[8]; j=0; while(inum>9 && j<7){ // zero is ascii 48: chbuf[j]=(char)48+ inum-((inum/10)*10); inum=inum/10; j++; if(decimalpoint_pos==j){ chbuf[j]='.'; j++; } } chbuf[j]=(char)48+inum; // most significant digit decimalpoint_pos--; while(j<decimalpoint_pos){ j++; chbuf[j]='0'; } if (spacepadd && j > (decimalpoint_pos+2)){ // no leading space padding needed spacepadd=0; } if(decimalpoint_pos==j){ j++; chbuf[j]='.'; j++; chbuf[j]='0'; // leading zero } if (spacepadd){ j++; chbuf[j]=' '; // leading space padding: "9.50" becomes " 9.50" } // now reverse the order i=0; while(j>=0){ outbuf[i]=chbuf[j]; j--; i++; } outbuf[i]='\0';}// convert voltage values to adc values, disp=10 is 1.0Vstatic int disp_u_to_adc(int disp){ return((int)(disp * 102.3) / (ADC_REF * U_DIVIDER));}// calculate the needed adc offset for voltage drop on the// current measurement shuntstatic int disp_i_to_u_adc_offset(int disp){ return(disp_u_to_adc(disp/20));}// convert adc values to voltage values, disp=10 is 1.0V// disp_i_val is needed to calculate the offset for the voltage drop over// the current measurement shuntstatic int adc_u_to_disp(int adcunits,int disp_i_val){ int adcdrop; adcdrop=disp_i_to_u_adc_offset(disp_i_val); if (adcunits < adcdrop){ return(0); } adcunits=adcunits-adcdrop; return((int)(((adcunits /102.3)* ADC_REF * U_DIVIDER)+0.6));}// convert adc values to current values, disp=10 needed to be printed// by the printing function as 0.10 Astatic int disp_i_to_adc(int disp){ return((int) (((disp * 10.23)* I_RESISTOR) / ADC_REF));}// convert adc values to current values, disp=10 needed to be printed// by the printing function as 0.10 Astatic int adc_i_to_disp(int adcunits){ return((int) (((adcunits* ADC_REF)/(10.23 * I_RESISTOR))+0.6));}// check the keyboardstatic signed char check_buttons(void){ if (check_u_button(&(set_val[1]))){ if(set_val[1]>U_MAX){ set_val[1]=U_MAX; } return(1); } if (check_i_button(&(set_val[0]))){ if(set_val[0]>I_MAX){ set_val[0]=I_MAX; } return(1); } if (check_store_button()){ lcd_clrscr(); lcd_puts_P("store not"); lcd_gotoxy(0,1); lcd_puts_P("implemented yet"); delay_ms(200); return(1); }; return(0);}void main(void){ char out_buf[20+1]; int measured_val[2]; measured_val[0]=0; measured_val[1]=0; init_dac(); lcd_init(LCD_DISP_ON); init_kbd(); set_val[0]=15;set_val[1]=50; // 150mA and 5V if (eeprom_read_byte((uint8_t *)0x0) == 19){ // ok magic number matches accept values set_val[1]=eeprom_read_word((uint16_t *)0x04); set_val[0]=eeprom_read_word((uint16_t *)0x02); } sei(); init_analog(); while (1) { // current measured_val[0]=adc_i_to_disp(getanalogresult(0)); set_val_adcUnits[0]=disp_i_to_adc(set_val[0]); set_target_adc_val(0,set_val_adcUnits[0]); // voltage measured_val[1]=adc_u_to_disp(getanalogresult(1),measured_val[0]); set_val_adcUnits[1]=disp_u_to_adc(set_val[1])+disp_i_to_u_adc_offset(measured_val[0]); set_target_adc_val(1,set_val_adcUnits[1]); // voltage lcd_clrscr(); int_to_ascii(measured_val[1],out_buf,1,1); lcd_puts(out_buf); lcd_puts("V "); int_to_ascii(set_val[1],out_buf,1,1); lcd_putc('['); lcd_puts(out_buf); lcd_putc(']'); if (!is_current_limit()){ // put a marker to show which value is currenlty limiting lcd_puts("<-"); } // current lcd_gotoxy(0,1); int_to_ascii(measured_val[0],out_buf,2,0); lcd_puts(out_buf); lcd_puts("A "); int_to_ascii(set_val[0],out_buf,2,0); lcd_putc('['); lcd_puts(out_buf); lcd_putc(']'); if (is_current_limit()){ // put a marker to show which value is currenlty limiting lcd_puts("<-"); } //dbg //int_to_ascii(is_dacval(),out_buf,0,0); //lcd_puts(out_buf); // the buttons must be responsive but they must not // scroll too fast if pressed permanently if (!check_buttons()){ // no buttons pressed delay_ms(100); check_buttons(); delay_ms(100); }else{ delay_ms(200); } }}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -