打印

PSoC ADC

[复制链接]
3655|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xinxinrenlei|  楼主 | 2011-11-17 17:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Go_PSoC 于 2011-11-17 23:04 编辑

听说psoc3/5的ADC有了很大改进,是吗
沙发
Go_PSoC| | 2011-11-17 22:54 | 只看该作者
对的。现在为20-bit resolution @ ± 0.1% Vref Accuracy

使用特权

评论回复
板凳
ascef| | 2011-11-20 22:40 | 只看该作者
不错!

使用特权

评论回复
地板
bettying| | 2011-11-28 21:42 | 只看该作者
PSOC3 ADC模组使用实例  2011-08-03 17:49
加入收藏
转发分享
人人网
开心网
新浪微博
搜狐博客
百度收藏
谷歌收藏
qq书签
豆瓣
淘江湖
Facebook
Twitter
Digg
Yahoo!Bookmarks
好久时间没有写博文了,今天终于有点空,来写一篇吧。今天我们来写AD模组及其使用。
PSOC3内置的模组是∑-Δ模数转换器,是目前应用比较广泛的一种AD转换器。在讲PSOC系统的∑-Δ模数转换器之前我们先来补习一些AD的基本知识。
一、什么是ADC?
       ADC,Analog-to-Digital Converter的缩写,指模/数转换器或者模拟/数字转换器。真实世界的模拟信号,例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字形式。模/数转换器可以实现这个功能,在各种不同的产品中都可以找到它的身影。
    模拟信号转换成数字信号的器件
二、ADC的几个关键参数
   1.基准电压Vref--------(转换器的满刻度电压)
  2. 位数(n)---ADC输出的二进制位数,n越大,分辨率就越高
  3. 分辨率:表示输出数字量变化一个最低有效位所对呀的输入模拟电压的变化量,其大小为:

4.量化误差:由于分辨率的关系造成真实值与转换值之间的误差
5.转换精度:是实际的ADC与理想的ADC相比的转换误差
6.转换时间:ADC完成一次AD转换所需的时间,转换时间与转换速率成倒数关系
三、ADC输出数字量与输入模拟量之间的关系
   设输入模拟电压为Vin,基准电压为Vref ,转换后的数字量为D,ADC的位数为n,这几个参数之间的关系为:
   
                  

所以:由上式我们可以看出,一个ADC的输出量与参考电压和位数有关,在设置时要注意这几点
四、∑-Δ模数转换器
        Σ一△模数转换器是一种高度集成化的新型模数转换器。采用过采样技术,无需采样一保持电路 ,其主要特性有:
      (1)可以配置的转换位数(8-20位可选)
        (2)11中可选的模拟电压输入范围     (分单极性4中和差分输入两种情况)
        (3)采样率10 SPS到384 ksps
        (4)4中工作模式
         (5) 可配置的输入缓存放大电路
实例,用PSOC3做一个0-3.3v的数字电压表
1.新建一个项目,命名为PSOC3-AD,打开原理图,放置一个ADC,一个LCD,如果是多路输入信号的话,还可以放置一个A-Mux(多路模拟开关),一个定时器,如图:

配置如图

编写如下代码:



/* ========================================
*
* Copyright YOUR COMPANY, THE YEAR
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF your company.
*
* ========================================
*/
#include
uint16 AD_Resulit = 0;
uint16 Channel = 0;
float C_to_V = 0.0;
uint8 Flag = 0;
#define ROW_0       0  /* LCD row 0     */
#define COLUMN_0    0  /* LCD column 0  */
#define COLUMN_9    9  /* LCD column 9  */
#define COLUMN_10  10  /* LCD column 10 */
#define COLUMN_11  11  /* LCD column 11 */
/* For clearing Tens and Hundreds place */
#define CLEAR_TENS_HUNDREDS "    "
/* For clearing Hundreds place */
#define CLEAR_HUNDREDS      "   "
void UpdateDisplay (float voltageRawCount,uint16 Channel);
void main()
{
ADC_Start();/*启动AD*/
LCD_Char_1_Start();
Timer_1_Start();
isr_Timer1_Start();
AMux_1_Start();
  ADC_Init();   /* 初始化AD */
ADC_Enable(); /*ADC使能*/
ADC_StartConvert(); /*AD开始转换*/
LCD_Char_1_Position(ROW_0,COLUMN_0); /*移动光标到(0,0)处 */
LCD_Char_1_PrintString("V Count: ");
AMux_1_Select(Channel);
    CYGlobalIntEnable;
   for(;;)
    {
  if(Flag == 0)
  {
   Timer_1_Stop() ;
      if(ADC_IsEndConversion() == ADC_RETURN_STATUS)  /* 判断转换是否结束. */
   {
   AD_Resulit = ADC_GetResult16();
   C_to_V = ADC_CountsTo_Volts(AD_Resulit);
   UpdateDisplay(C_to_V, Channel);
   Flag = 1;
   Timer_1_Start();
   Channel++;
   if (Channel == 4)
      Channel = 0;
   AMux_1_Select(Channel);
   }
   }
    }
}

void UpdateDisplay (float voltageRawCount,uint16 Channel)
{
    int Integer,Decimal;        /*定义两个变量分别存整数部分和小数部分*/
Integer = (int) voltageRawCount;
Decimal = (int) ((voltageRawCount - Integer)*1000)+1;   /*分别取出小数部分和小数部分,保留3位小数*1000,两位*100*/
    LCD_Char_1_Position(ROW_0,COLUMN_9); /* 移动光标到(0,9) */
    LCD_Char_1_PrintNumber(Integer); /* 输出整数部分 */
    LCD_Char_1_PrintString(".");        /* 输出小数点*/
LCD_Char_1_PrintNumber(Decimal);   /*输出小数部分*/
LCD_Char_1_Position(1,0);
LCD_Char_1_PrintString("Channel: ");
LCD_Char_1_PrintNumber(Channel);

}

连接硬件,观看工作效果

使用特权

评论回复
5
bettying| | 2011-11-28 21:43 | 只看该作者
/* ========================================
*
* 程序名称: PSOC3与LM92之间的数据通讯
* 功能描述: 用PSOC3通过I2C总线实现温度采集并显示在1602液晶显示器上
* 使用模块;  I2C主机模块
* 作    者: 万选明
* 完成时间: 2011年3月28日
* 备    注:    无
* ========================================
*/
#include
/*以下是用到的函数声明*/
float Tempture(uint8 slaveAddr);                           //函数声明
void UpdateDisplay (float voltageRawCount,uint16 Channel); //显示函数
void Delay(uint16 Time);                                   //延时函数
void UART_TX_float(float data1);

#define  LM92_Addr  (0x48u)                                //定义LM82从机地址
float Temp = 0.0;                                          //存温度变量
void main()
{
uint8 Data = 0;
    CYGlobalIntEnable;
  I2C_1_Start();                                        //I2C总线启动开始
  LCD_Char_1_Start();                                   //1602启动开始
UART_1_Start();
    LCD_Char_1_Position(0,0);
/*移动光标到(0,0)处 */
    LCD_Char_1_PrintString("Tempture: ");                 /*显示Tempture: */
UART_1_ClearRxBuffer();
//  UART_1_EnableRxInt();
// UART_1_EnableRxInt();
// UART_1_SetRxInterruptMode(UART_RX_STS_FIFO_NOTEMPTY) ;

    for(;;)
    {

  

//{
     Temp = Tempture(LM92_Addr);                           /* 读取温度值 */
  UpdateDisplay (Temp,1);                               /*显示温度数据 */
     Delay(500);                                           /*延时 */
if ( UART_1_ReadRxData()== 0x48)    //是本机地址,发送温度数据
{
     UART_TX_float(Temp);                 //发送温度数据
}

// }
    }
}
/* ========================================
*
* 函数名称:float Tempture(uint8 slaveAddr)
* 功能描述:从从机中读取数字温度值并转换成实际温度
* 参    数; slaveAddr--从机地址
* 返    回:TEMP -- 实际温度值
* 完成时间:2011年3月28日
* 备    注:    无
* ========================================*/
float Tempture(uint8 slaveAddr)
{
uint8 Status;
int Data[4];
float TEMP;
I2C_1_MasterClearStatus();                                            //清除I2C状态数据
Status =I2C_1_MasterSendStart(slaveAddr, I2C_1_READ_XFER_MODE);      //发送读数据命令
if(Status == I2C_1_MSTR_NO_ERROR)                                    /* 判断状态 */
{
/* 读回温度数据 */
Data[0] = I2C_1_MasterReadByte(I2C_1_ACK_DATA);                   //读取温度数据高8位
Data[1] = I2C_1_MasterReadByte(I2C_1_ACK_DATA);                   //读取温度数据低8位
Data[2] = I2C_1_MasterReadByte(I2C_1_NAK_DATA);                   //温度读完读NCK信号
}
I2C_1_MasterSendStop();                                          /* 发送停止 */
Data[3] = (Data[0] <<8)| (Data[1] & 0x00ff)  ;                   //温度数据合并
Data[3] >>= 3 ;                                                  //温度从中高12位,为转换方便移到第十二位
if (Data[3] & 0x1000)        // 是负数
{
  Data[3] &= 0x0fff;               
  Data[3] = ~Data[3] + 1;    // 补码运算
  TEMP = -0.0625 * Data[3];   // 求出温度值
}
else
{
  TEMP = 0.0625 * Data[3];           
}

return (TEMP);

}
/* ========================================
*
* 函数名称:void UpdateDisplay (float voltageRawCount,uint16 Channel)
* 功能描述:显示数据
* 参    数; Data--显示的数据
* 返    回:无
* 完成时间:2011年3月28日
* 备    注:    无
* ========================================*/
void UpdateDisplay (float Data,uint16 Channel)
{
    int Integer,Decimal;        /*定义两个变量分别存整数部分和小数部分*/
Integer = (int) Data;
Decimal = (int) ((Data - Integer)*1000)+1;   /*分别取出小数部分和小数部分,保留3位小数*1000,两位*100*/
    LCD_Char_1_Position(0,9); /* 移动光标到(0,9) */
    LCD_Char_1_PrintNumber(Integer); /* 输出整数部分 */
    LCD_Char_1_PrintString(".");        /* 输出小数点*/
LCD_Char_1_PrintNumber(Decimal);   /*输出小数部分*/
LCD_Char_1_Position(1,0);
LCD_Char_1_PrintString("Channel: ");
LCD_Char_1_PrintNumber(Channel);

}
/* [] END OF FILE */
/* ========================================
*
* 函数名称:void Delay(int8 Time)
* 功能描述:延时
* 参    数; time--yan时时间
* 返    回:无
* 完成时间:2011年3月27日
* 备    注:    无
* ========================================*/
void Delay(uint16 Time)
{
     int i=0,j=0 ;
  for(j=0;j
  {
  for (i=0;i<1000;i++);
  }

}


//****************************************************************************
//函数名:UART_TX_float(float data)
//功能:通过串口发送浮点数
//参数: data;要发送的浮点数
//返回: 无
//****************************************************************************
void UART_TX_float(float data1)
{
int High_data,Low_data,Mid_data;
Mid_data =(int)(data1*100);           //取小数点后两位数字上传
Low_data = Mid_data & 0x00ff;
High_data = (Mid_data & 0xff00)>>8;
UART_1_WriteTxData(0x48);         //回送本机地址
UART_1_WriteTxData(High_data);  //发送温度数据的高8位数据 UART_1_WriteTxData(Low_data);  //发送温度数据的低8位数据

}
当然,这个程序最好用中断的方式来实现,但由于时间关系,我没有测试,感兴趣的朋友可以测试后,把你的代码与我共享,在此声明,本程序仅是用来学习,与实际工程还有很大差异,有很多BUG,下位机的现象与上讲一样,在此不在重述。
/* [] END OF FILE */

使用特权

评论回复
6
zfytkb| | 2011-11-30 14:32 | 只看该作者
LZ,**很好,就是漏了一点,“ADC输出数字量与输入模拟量之间的关系”计算公式没写出来,希望你可以补上

使用特权

评论回复
7
xinxinrenlei|  楼主 | 2011-11-30 19:11 | 只看该作者
谢谢大家

使用特权

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

本版积分规则

4

主题

51

帖子

0

粉丝