打印
[资源共享]

《芯圣51内核单片机HC89F0xx库分享》-ADC 库

[复制链接]
23393|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
正版长小强|  楼主 | 2023-11-23 09:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#申请原创# #每日话题# #技术资源#《芯圣51内核单片机HC89F0xx库分享》- ADC库
一、前言
       项目需要近期接触芯圣HC89F0xx系列51核单片机 ,超高的 性价比、灵活性 深深的吸引了我 。 为后续项目更快落地,开始做基础功能的封装库工作。

       往期分享地址 : 软定时器  、 GPIO库  

二、分享内容
      ADC 功能在项目中应用广泛 ,芯圣89f0xx 系列提供一组ADC ,最多16路采集通道,满足大多数应用需求。实际项目通道需求数量不固定 ,面临移植困难
      库亮点:无需了解 ANx通道 ,只需要知道这个gpio 是否支持 ADC 即可 完成基础配置
                   采集实时,ADC 完成采集后会执行回调函数
                   多通道的自动链表队列,相同方式完成多通道分时配置
     使用方法:
      /*********************************************例子************************************************
xdata  struct HC_adc_m  ADC_Get_1;  
xdata  struct HC_adc_m  ADC_Get_2;
void  ADC_Get_val_1(struct HC_adc_m *ADC,unsigned int val)
{
    xxx = val;   //取得ADC 转化结果
}
void  ADC_Get_val_2(struct HC_adc_m *ADC,unsigned int val)
{
    xxx = val;//取得ADC 转化结果
}
void main (void)
{
        Main_Iint();
    ADC_Config(ADC1_PIN,ADC_Get_val_1,&ADC_Get_1);  //模拟量1
    ADC_Config(ADC2_PIN,ADC_Get_val_2,&ADC_Get_2);  //模拟量2
    while(1)
    {

    }
}
三、源码分享
  
#include "x_gpio.h"
#include "x_mainrun.h"

#include "x_adc.h"


xdata    struct HC_adc_m  *HC_adc_Rp;   //工作队列
xdata    struct HC_adc_m  *HC_adc_Ep;   //队列结束

xdata new_t   adc_Read_t;              //周期转换心跳
/*
    ADC 通道关联的端口
    AN0 - AN7   P0
    AN8 - AN15  P2
*/

static void Get_ADC_Run(void);

/*************************************************
*ADC 基础寄存器配置
*参数 无
*返回 无
*************************************************/
static void  ADC_Reg_Init(void)
{
            ADCC0 = 0;                  //内部参考电压VDD,ADCIF=0,关闭ADC电源
            ADCC2 = 0x4d;               //0b01 001 101  ADCL=0(12bit),ALIGN=1(右对齐),ADCTS=001 ADCS=101(ADC时钟=Fosc/16=1M)   
            ADCC0 |= (1 << 7);          //开启ADC电源:ADCEN = 1
            ADCC0 &= ~(1 << 5);         //清除ADCIF(启动转换时,ADCIF需要先清0)

        
        new_time_create(&adc_Read_t,NEW_TIME_TICK_SEC / 100,NEW_TIME_MODE_WHILE,Get_ADC_Run);
        new_time_cmd(&adc_Read_t, NEW_TIME_ON);
        
}
/*************************************************
*ADC 通道配置
*ch :配置通道
*返回 无
*************************************************/
unsigned char  ADC_Config(unsigned char Pin_BCD,void (*get_ADC)(unsigned int val),struct HC_adc_m *ADC)
{
    static unsigned char startflag = 0;
    xdata strChar  Set_Pin;
    xdata unsigned char ch;
    //换算ANx 通道
    Set_Pin.byte = Pin_BCD;
    switch(Set_Pin.half.low)
    {
        case 0: ch =  Set_Pin.half.high;         break;
        case 2: ch =  8 + Set_Pin.half.high;     break;
        default :  return 0;     break;
    }
    ADC->get_ADC = get_ADC;
    ADC->ANx = ch;
    Pin_Mode_Set(Pin_BCD,GPIO_Mode_IN_FLOATING);    //IO模式配置

    if(startflag == 0)            //执行一次
    {
        startflag = 1;
        ADC_Reg_Init();             //基础寄存器配置
            ADCC1 = ch;               //选择AN2(P02)为ADC采样通道  
            ADCC0 |= (1 << 6);        //启动ADC转换:ADCST = 1
            
        HC_adc_Rp = ADC;  
        HC_adc_Ep = ADC;
        HC_adc_Ep->up = ADC;
        HC_adc_Ep->down= ADC;
     }
    else
    {
        ADC->down = HC_adc_Ep;
        ADC->up = HC_adc_Ep->up;
        
        ADC->up->down = ADC;
        HC_adc_Ep->up =ADC;

        HC_adc_Ep = ADC;
    }
   
    return 1;
}



/*************************************************
  *ADC 通道采集值
  *参数 无
  *返回 无
*************************************************/
static void Get_ADC_Run(void)
{
        if ((ADCC0 & 0x20) == 0x20)    //采样完成ADCIF=1
        {
                ADCC1 = (ADCC1&(~0x07)) | HC_adc_Rp->up->ANx;  //通道切换 需要与启动转换间隔 20us
                ADCC0 &= ~(0x20);        //清转换完成/中断标志位;
                HC_adc_Rp->get_ADC(HC_adc_Rp,ADCR);  //执行回调函数
    HC_adc_Rp = HC_adc_Rp->up;
               
                ADCC0 |= (0x40);           //启动ADC转换:ADCST = 1
        }
}
#ifndef __X_ADC_H__ 
#define __X_ADC_H__

#include "x_include.h"


struct HC_adc_m
{
     unsigned char ANx;                     //所属ANx通道
     void (*get_ADC)(struct HC_adc_m *ADC,unsigned int val);     //转换完成回调函数
    /*链表内部用*/
     struct HC_adc_m *up;
     struct HC_adc_m *down;
};

/*************************************************
*所需模拟量配置
*  Pin_BCD :IO 端口
*  get_ADC 转换完成后会调用这个函数
*  ADC ADC 通道数据结构载体
*返回 0 这个端口不支持 ADC 返回 1配置成功
*************************************************/
extern unsigned char  ADC_Config(unsigned char Pin_BCD,void (*get_ADC)( struct HC_adc_m *ADC,unsigned int val),struct HC_adc_m *ADC);
#endif


注意:代码依赖我们的软件定时器实现 自动队列转换功能
四、精彩预告   (基于 ADC 库 做 NTC (温度)传感器驱动)
亮点 : 提供 NTC  GPIO  就完成了 配置 , 提供 温度 上下限报警 、传感器异常  多状态回调通知  。
            支持多传感器 ,真的不要太简单  

列举两个 NTC 温度传感器
xdata  struct   NTC_m  NTC1;
xdata  struct   NTC_m  NTC2;

void  NTC1_Eve(struct   NTC_m  *NTC)
{
    //这里进行事件状态定位并进行需要的动作
    switch(NTC->temp.status)
        {
            case NTC_E1:  break;
            case NTC_E2:  break;

            case NTC_OK:  break;
            case NTC_W_LOW:  break;
            case NTC_W_HIGH:  break;
    }
}
void main (void)
{
                Main_Iint();
    NTC_Init(NTC1_PIN,&NTC1);
    NTC_Init(NTC2_PIN,&NTC2);
    NTC_Warning_Set(20,40,&NTC1);
    NTC_EVERun_Set(NTC1_Eve,&NTC1);
   
    while(1)
    {
        NTC1.temp.temp  //温度值
    }
}

  



使用特权

评论回复
评论
21小跑堂 2023-11-23 15:15 回复TA
奖励200家园币 
沙发
ljkok| | 2023-12-24 09:44 | 只看该作者
学习了,感谢大佬分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

194

帖子

4

粉丝