⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddcp.c

📁 一个非常好的电源设计程序
💻 C
字号:
/********************************************** 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);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -