专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

单片机可控0-30V可调电源

作者:佚名   来源:本站原创   点击数:  更新时间:2013年11月13日   【字体:

CPU电路图


显示电路


控制板电路图
 

程序
 
#include <iotiny24.h>                  // 包含型号头文件

//#include <iot24v.h>
#include <iomacro.h>                   // 包含"位"操作头文件
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

 
#define uchar unsigned char
#define uint  unsigned int

 
#define TRUE  1
#define FALSE 0

 
#define ad_Temp_flag  0x03          // 温度转换通道
#define ad_Vout_flag  0x04          // 电压转换通道
#define ad_Iout_flag  0x05          // 电流转换检测

 

 
#define FAN_ON    (PORTB_Bit3 = 1)  // FAN 开
#define FAN_OFF   (PORTB_Bit3 = 0)  // FAN 关

 
#define D1_ON     (PORTA_Bit0 = 0)  // D1 开
#define D1_OFF    (PORTA_Bit0 = 1)  // D1 关

 
#define D2_ON     (PORTA_Bit1 = 0)  // D2 开
#define D2_OFF    (PORTA_Bit1 = 1)  // D2 关

 
#define D3_ON     (PORTA_Bit2 = 0)  // D3 开
#define D3_OFF    (PORTA_Bit2 = 1)  // D3 关

 
#define D4_ON     (PORTB_Bit2 = 0)  // D4 开
#define D4_OFF    (PORTB_Bit2 = 1)  // D4 关

 
#define D5_ON     (PORTA_Bit6 = 0)  // D5 开
#define D5_OFF    (PORTA_Bit6 = 1)  // D5 关

 
#define D6_ON     (PORTA_Bit7 = 0)  // D6 开
#define D6_OFF    (PORTA_Bit7 = 1)  // D6 关

 
#define DATA164_ON  (PORTB_Bit1 = 1)   // 74HC164 DATA=1
#define DATA164_OFF (PORTB_Bit1 = 0)   // 74HC164 DATA=0

 
#define CLK164_ON   (PORTB_Bit0 = 1)   //
#define CLK164_OFF  (PORTB_Bit0 = 0)   //

 

 
#define Temp_out_lo 0x339            // -5℃ 41.56K  
#define Temp_out_hi 0x10e            // 50℃ 3.588K

 
uint   ad_Temp_result;               // 温度转换结果
uint   ad_Vout_result;               // 电压转换结果
uint   ad_Iout_result;               // 电流转换结果

 
uint   Vout_disp;
uint   Iout_disp;

 
uint   Iout_adj;

 
uchar  time_cnt1;
uchar  adc_get_flag;

 
//#pragma vector=0x10; 
//__interrupt void TIMER2_OVF_Server(void);

 
void mcu_init(void);                 // I/O初始化,PWM初始化
void adc_init(void);                 // ADC初始化
uint adc_get(uchar adc_ch);          // 启动AD转换,并返回转换值
void Vout_adc_get(void);             // 电压检测
void Temp_adc_get(void);             // 温度检测
void Iout_adc_get(void);             // 电流检测
//数码管显示代码定义 
__flash uchar disp_led[10] @0x0040 = 
  0x0a,                                 // '0' 
  0x7b,                                 // '1' 
  0x4c,                                 // '2' 
  0x58,                                 // '3' 
  0x39,                                 // '4' 
  0x98,                                 // '5' 
  0x88,                                 // '6' 
  0x5b,                                 // '7' 
  0x08,                                 // '8' 
  0x18,                                 // '9' 
};
/******************************************************************************/
//延时函数  
void delay_1us(void)                 // 1us延时函数
{
  asm("nop");
}
void delay_nus(uchar n)              // N us延时函数
{
  for(;n>0;n--)
    {
      delay_1us();
    }
}
                                     // 内部晶振频率为8MHz
void delay_1ms(void)                 // 1ms延时函数
{
  uint i;
  for(i=1142;i>0;i--);               // 8*143-2
}  
void delay_nms(uchar n)              // N ms延时函数
{
  for(;n>0;n--)
    {
      asm("wdr");                    // 喂狗
      delay_1ms();
    }   
}
/*******************************************************************************
函数名:mcu_init()
作用:I/O初始化,PWM初始化
输入:无
返回值:无
*******************************************************************************/
void mcu_init(void)
  SREG  |= 0x80;                   // 全局中断使能
  DDRB   = 0x0f;                     // PB口全部为输出
  PORTB  = 0x04;                     // 初始化PB口
  DDRA   = 0xc7;                     // PA3,PA4,PA5为输入
  PORTA  = 0xc7;                     // 初始化PA口
  CLKPR  = 0x80;                     // CLKPCE=1 修改系统时钟分频使能
  CLKPR  = 0x00;                     // 1分频 
  TCCR1B = 0x00;                     // TIMER1停止计数
  TCNT1H = 0x40;                     // 初值高8位
  TCNT1L = 0x00;                     // 初值低8位
  TIMSK1_Bit0 = 1;                   // TIMER1使能
  D1_OFF;
  D2_OFF;
  D3_OFF;
  D4_OFF;
  D5_OFF;
  D6_OFF;
  TCCR1B = 0x01;                     // TIMER1开始计数,1分频       
}
/*******************************************************************************
函数名:adc_init()
作用:adc初始化
输入:无
返回值:无
*******************************************************************************/
void adc_init(void)
{
  ADCSRA = 0x00;                     // 设置前,先关闭ADC              
  ADMUX  = 0x00;                     // 选择外部VCC为基准,ADC0通道
  ADCSRB = 0x00;                     // AD转换结果左对齐,(10位)
                                     // 使能ADC,启动ADC单次转换,8分频
  ADCSRA = 0xc3;      
}
/*******************************************************************************
函数名:wdt_init()
作用:看门狗初始化
输入:无
返回值:无
*******************************************************************************/
void wdt_init(void)
{
  asm("wdr");                        // clr wdt
  WDTCSR=0x1f;
  WDTCSR=0x0f;                       // enable wdt,clk = 256,2S
/*******************************************************************************
函数名:adc_get(uchar adc_ch)
作用:启动AD转换,并返回转换值
输入:adc_ch (AD转换通道)
返回值:adddata
*******************************************************************************/
uint adc_get(uchar adc_ch)
{  
  uint addata=0;                     // AD转化初始数据为0
  uchar i;  
  asm("wdr");                        // 喂狗
  ADMUX  = adc_ch;                   // adc_ch为ADC通道选择
  for(i=10;i>0;i--)
    {
      ADCSRA_Bit6 = 1;               // 启动ADC转换
      while((ADCSRA & 0x10) == 0);   // 等待转换结束,ADIF=1
    }
  addata=ADCL;     // 读取低8位数据
  addata+=ADCH*256;     // 读取高2位数据
  return addata;     // 返回8位数据
}
/*******************************************************************************
函数名: Vout_adc_get()
作用:电池电压检测,检测20次求平均值
输入:无
返回值:无
*******************************************************************************/
void Vout_adc_get(void)
{  
  uchar n=0;
  ad_Vout_result=0;  
  asm("wdr");                        // 喂狗
  for(n=0;n<10;n++)
    {
      asm("wdr");                    // 喂狗
      ad_Vout_result += adc_get(ad_Vout_flag);
    }
  ad_Vout_result = ad_Vout_result/10; 
}  
/*******************************************************************************
函数名: Temp_adc_get()
作用:电池温度检测,检测20次求平均值
输入:无
返回值:无
*******************************************************************************/
void Temp_adc_get(void)
{
  uchar n=0;
  ad_Temp_result=0;
  asm("wdr");                        // 喂狗
  for(n=0;n<10;n++)
    {
      asm("wdr");                    // 喂狗
      ad_Temp_result += adc_get(ad_Temp_flag);
    }
  ad_Temp_result = ad_Temp_result/10;    
}
/*******************************************************************************
函数名: Iout_adc_get()
作用:电流检测,检测20次求平均值
输入:无
返回值:无
*******************************************************************************/
void Iout_adc_get(void)
{
  uchar n=0;
  ad_Iout_result=0;
  asm("wdr");                        // 喂狗
  for(n=0;n<10;n++)
    {
      asm("wdr");                    // 喂狗
      ad_Iout_result += adc_get(ad_Iout_flag);
    }
  ad_Iout_result = ad_Iout_result/10;    
}
/*******************************************************************************
函数名:Send_164_data()
作用:送164数据
输入:disp_data
返回值:无
*******************************************************************************/
void Send_164_data(uchar disp_data)
{
   uchar i;
   asm("wdr");                        // 喂狗
   CLK164_OFF;
   for(i=0;i<8;i++)
     {
       asm("wdr");                    // 喂狗
       if(disp_data&0x80)
         {
           DATA164_ON;
         }
       else
         {
           DATA164_OFF;
         }
       CLK164_ON;   
       disp_data<<=1;
       CLK164_OFF;
     }
}
/*******************************************************************************
函数名:disp_data_adc()
作用:显示数据处理
输入:无
返回值:无
*******************************************************************************/
void disp_data_adc(void)
{
   Vout_adc_get();
   Vout_disp = ad_Vout_result * 50;
   Vout_disp = Vout_disp / 128;
   Iout_adc_get();
   Iout_disp = ad_Iout_result * 50;
   Iout_disp = Iout_disp / 102;
   Iout_adj = (Vout_disp * 10) / 75;
   if((Iout_disp - Iout_adj) < 0x0fff)
     {      
       Iout_disp = Iout_disp - Iout_adj;
     }
   else
     {
       Iout_disp = 0;
     }
}   
/*******************************************************************************
函数名:delay()
作用:延时。。
输入:无
返回值:无
*******************************************************************************/
void delay(void)
{
   if(adc_get_flag == 0)
     {
       disp_data_adc();
       adc_get_flag=1;
     }
   else
     {
       delay_nms(20);    
     }
}    
/*******************************************************************************
函数名:display_led()
作用:数码管显示
输入:无
返回值:无
*******************************************************************************/
void display_led(void)
{
   asm("wdr");                        // 喂狗  
   Send_164_data(disp_led[Vout_disp  / 100]);
   D1_ON;
   delay();
   D1_OFF;
   Send_164_data(disp_led[(Vout_disp % 100) / 10] - 0x08);
   D2_ON;
   delay();
   D2_OFF;
   Send_164_data(disp_led[(Vout_disp % 100) % 10]);
   D3_ON;
   delay();
   D3_OFF;
   Send_164_data(disp_led[Iout_disp  / 100] - 0x08);
   D4_ON;
   delay();
   D4_OFF;
   Send_164_data(disp_led[(Iout_disp % 100) / 10]);
   D5_ON;
   delay();
   D5_OFF; 
   Send_164_data(disp_led[(Iout_disp % 100) % 10]);
   D6_ON;
   delay();
   D6_OFF;  
}
/*******************************************************************************
函数名: time1_ovf()
作用:TIMER1定时器中断服务程序,8M 50ms中断一次,4M 25ms中断一次
输入:无
返回值:无
*******************************************************************************/
#pragma vector=TIM1_OVF_vect 
__interrupt void time1_ovf(void) 
{
  TCNT1H = 0x40;
  TCNT1L = 0x00;
  asm("wdr");                        // 喂狗 
  time_cnt1++;
  if(time_cnt1==50)                  // 
    {
      asm("wdr");                    // 喂狗
      time_cnt1=0;
      adc_get_flag=0;
    }
}
/*******************************************************************************
主函数
*******************************************************************************/
void main(void)
{
  mcu_init();                        // 单片机初始化
  adc_init();                        // AD转换初始化
  wdt_init();                        // 看门狗初始化
  while(1)
    { 
      display_led();  
    }  
}

 MCU型号: AT Tiny24
功能说明:0-30V 可调电源  显示电压及电流
引脚说明;PA0/ADC0--D1 电压
          PA1/ADC1--D2 电压
          PA2/ADC2--D3 电压
          PA3/ADC3--RT
 PA4/ADC4--Vout
          PA5/ADC5--Iout
          PA6/ADC6--D5 电流
          PA7/ADC7--D6 电流
          PB2/    --D4 电流
          PB3/RESET--FAN
          PB1     --74HC164 DATA
          PB0     --74HC164 SCK
关闭窗口

相关文章