本次测试目的为了测试板子的ADC功能,并将检测结果通过OLED显示出来。
一、硬件连接
通过原理图,找到A0引脚,将A0与信号发生器接通,注意电压不要超过3.3,通过OLED观察ADC采集值。
二,程序编写
main.c文件
#include "dsc_config.h"
#include <syscalls.h>
#include "IQmathLib.h"
#include "IIC_OLED.h"
#include "ADC.h"
void INTERRUPT timer0_ISR(void);
Uint16 adc_num=0,ge=0,xiao1=0,xiao2=0;
int main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.TINT0 = &timer0_ISR;
EDIS;
InitCpuTimers();
ConfigCpuTimer(&CpuTimer0, 60, 100000);
CpuTimer0Regs.TCR.all = 0x4000;
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
OLED_Init();
InitAdc();
ADC_Init();
EINT;
ERTM;
while(1){
OLED_ShowCHinese(1,1,1);
OLED_ShowCHinese(1,2,2);
OLED_ShowChar(1,5,':');
OLED_ShowNum(1,6,ge,1);
OLED_ShowChar(1,7,'.');
OLED_ShowNum(1,8,xiao1,1);
OLED_ShowNum(1,9,xiao2,1);
}
return 0;
}
void INTERRUPT timer0_ISR(void)
{
adc_num=(int)(read_adc()*100);
ge=adc_num/100;
xiao1=adc_num%100/10;
xiao2=adc_num%100%10;
EALLOW;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
EDIS;
}
ADC.c文件
#include "ADC.h"
/******************************************************************
*函数名:void ADC_Init()
*参 数:无
*返回值:无
*作 用:配置ADC
******************************************************************/
void ADC_Init(void)
{
EALLOW;
AdcRegs.ADCCTL2.bit.CLKDIV2EN =1;//设置采集频率30M
/*NT脉冲产生在ADC结果锁定到其结果寄存器之前发生一个周期*/
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;
/*中断选择1寄存器*/
AdcRegs.INTSEL1N2.bit.INT1E = 1;
/*每当产生EOC脉冲时,都会产生附加脉冲,而不管是否清除了标记位*/
AdcRegs.INTSEL1N2.bit.INT1CONT= 0;
/*EOC6是ADCINT3的触发器*/
AdcRegs.INTSEL1N2.bit.INT1SEL = 0;
AdcRegs.ADCSAMPLEMODE.all = 0;
/*将SOC0设置为样本A0*/
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0;
/*SOCx触发源选择:ADCTRIG5-ePWM1,ADCSOCA*/
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1;
/*采样窗口长达6个周期(2n+6个时钟周期)*/
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;
EDIS;
}
float read_adc()
{
static float adc_count;
adc_count=(float)AdcResult.ADCRESULT0*3.3/4096;
/*清除ADCINTFLG寄存器中各自的标志位*/
AdcRegs.ADCINTFLGCLR.all= 0xFF;
return adc_count;
}
ADC.h文件
#ifndef __ADC_H
#define __ADC_H
#include "dsc_config.h"
extern void ADC_Init(void);
extern float read_adc();
#endif
OLED.c文件
#include "IIC_OLED.h"
#include "OLED_Font.h"
#define IIC_SCL_SETH (GpioDataRegs.GPBSET.bit.GPIO33=1)
#define IIC_SCL_SETL (GpioDataRegs.GPBCLEAR.bit.GPIO33=1)
#define IIC_SDA_SETH (GpioDataRegs.GPBSET.bit.GPIO32=1)
#define IIC_SDA_SETL (GpioDataRegs.GPBCLEAR.bit.GPIO32=1)
#define READ_SDA (GpioDataRegs.GPBDAT.bit.GPIO32)
unsigned char GRAM[1024];
void delay_Xus(Uint16 X)//dely1.2us
{
static Uint16 i=0;
while(X--)
{
for(i=0;i<1;i++){}
}
}
//unsigned char xin[]={0x0c,0x12,0x21,0x42,0x84,0x42,0x21,0x12,0x0c};
/**
* [url=home.php?mod=space&uid=2666770]@Brief[/url] OLED写命令
* [url=home.php?mod=space&uid=3142012]@param[/url] Command 要写入的命令
* @retval 无
*/
void OLED_WriteCommand(unsigned char Command)
{
IIC_Start();
IIC_Send_Byte(0x78); //从机地址
IIC_NAck();
IIC_Send_Byte(0x00); //写命令
IIC_NAck();
IIC_Send_Byte(Command);
IIC_NAck();
IIC_Stop();
}
/**
* @brief OLED写数据
* @param Data 要写入的数据
* @retval 无
*/
void OLED_WriteData(unsigned char Data)
{
IIC_Start();
IIC_Send_Byte(0x78); //从机地址
IIC_NAck();
IIC_Send_Byte(0x40); //写数据
IIC_NAck();
IIC_Send_Byte(Data);
IIC_NAck();
IIC_Stop();
}
/**
* @brief OLED设置光标位置
* @param Y 以左上角为原点,向下方向的坐标,范围:0~7
* @param X 以左上角为原点,向右方向的坐标,范围:0~127
* @retval 无
*/
void OLED_SetCursor(unsigned char Y, unsigned char X)
{
if(OLED_SIZE_13==1)
{
OLED_WriteCommand(0xB0 | Y); //设置Y位置
OLED_WriteCommand(0x10 | (((X+2) & 0xF0) >> 4)); //设置X位置高4位
OLED_WriteCommand(0x00 | ((X+2) & 0x0F)); //设置X位置低4位
}
if(OLED_SIZE_096==1)
{
OLED_WriteCommand(0xB0 | Y); //设置Y位置
OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位
OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位
}
}
/**
* @brief OLED清屏
* @param 无
* @retval 无
*/
void OLED_Clear(void)
{
unsigned char i, j;
for (j = 0; j < 8; j++)
{
OLED_SetCursor(j, 0);
for(i = 0; i < 128; i++)
{
OLED_WriteData(0x00);
}
}
}
/**
* @brief OLED显示一个字符
* @param Line 行位置,范围:1~4
* @param Column 列位置,范围:1~16
* @param Char 要显示的一个字符,范围:ASCII可见字符
* @retval 无
*/
void OLED_ShowChar(unsigned char Line, unsigned char Column, char Char)
{
unsigned char i;
OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分
for (i = 0; i < 8; i++)
{
OLED_WriteData(OLED_F8x16[Char - ' '][i]); //显示上半部分内容
}
OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分
for (i = 0; i < 8; i++)
{
OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]); //显示下半部分内容
}
}
/**
* @brief OLED显示一个汉字
* @param Line 行位置,范围:1~4
* @param Column 列位置,范围:1~8
* @param Hzk:汉字库
* @retval 无
*/
void OLED_ShowCHinese(Uint16 Line,Uint16 Column,Uint16 no)
{
Uint16 t;
OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16); //设置光标位置在上半部分
for(t=0;t<16;t++)
{
OLED_WriteData(Hzk[2*(no-1)][t]); //显示上半部分内容
}
OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16); //设置光标位置在下半部分
for(t=0;t<16;t++)
{
OLED_WriteData(Hzk[2*(no-1)+1][t]); //显示上半部分内容
}
}
/**
* @brief OLED显示字符串
* @param Line 起始行位置,范围:1~4
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串,范围:ASCII可见字符
* @retval 无
*/
void OLED_ShowString(unsigned char Line, unsigned char Column, char *String)
{
unsigned char i;
for (i = 0; String[i] != '\0'; i++)
{
OLED_ShowChar(Line, Column + i, String[i]);
}
}
/**
* @brief OLED次方函数
* @retval 返回值等于X的Y次方
*/
unsigned int OLED_Pow(unsigned int X, unsigned int Y)
{
unsigned int Result = 1;
while (Y--)
{
Result *= X;
}
return Result;
}
/**
* @brief OLED显示数字(十进制,正数)
* @param Line 起始行位置,范围:1~4
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~4294967295
* @param Length 要显示数字的长度,范围:1~10
* @retval 无
*/
void OLED_ShowNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
{
unsigned char i;
for (i = 0; i < Length; i++)
{
OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
}
}
/**
* @brief OLED初始化
* @param 无
* @retval 无
*/
void OLED_Init(void)
{
IICA_Init(); //端口初始化
unsigned int i, j;
for (i = 0; i < 1000; i++) //上电延时
{
for (j = 0; j < 1000; j++);
}
OLED_WriteCommand(0xAE); //关闭显示
OLED_WriteCommand(0x20); //设置内存地址模式
OLED_WriteCommand(0x02); //00水平地址模式,01垂直地址模式,02页面地址模式
OLED_WriteCommand(0x00); //设置列起始低位,0x10设置列起始高位
OLED_WriteCommand(0x40); //设置显示开始行:显存中的第几行作为屏幕的第一行
OLED_WriteCommand(0xB0); //设置目标显存位置页起始地址:B0-B7
OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率
OLED_WriteCommand(0x80);
OLED_WriteCommand(0xA8); //设置多路复用率(0-63)
OLED_WriteCommand(0x3F); //00-3F
OLED_WriteCommand(0xD3); //设置屏幕上下偏移
OLED_WriteCommand(0x00); //00-FF
OLED_WriteCommand(0xA1); //设置左右镜像,0xA1正常 0xA0左右反置
OLED_WriteCommand(0xC8); //设置上下镜像,0xC8正常 0xC0上下反置
OLED_WriteCommand(0xDA); //设置COM引脚硬件配置
OLED_WriteCommand(0x12);
OLED_WriteCommand(0x81); //设置对比度控制
OLED_WriteCommand(0xCF); //00-FF,256级
OLED_WriteCommand(0xD9); //设置预充电周期
OLED_WriteCommand(0xF1);
OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别
OLED_WriteCommand(0x30);
OLED_WriteCommand(0xA4); //A4显示显存内容,A5无视显存内容点亮全屏
OLED_WriteCommand(0xA6); //正常显示0xA6/整体反显0xA7
OLED_WriteCommand(0x8D); //设置充电泵
OLED_WriteCommand(0x14);
OLED_WriteCommand(0xAF); //开启显示
OLED_Clear(); //OLED清屏
}
/*******************************************************************************
* 函 数 名 : IIC_Init
* 函数功能 : IIC初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IICA_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0; //上拉
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1; // 输出端口
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0; // IO口
GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 2; // 不同步
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0; //上拉
GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1; // 输出端口
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0; // IO口
GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 2; // 不同步
EDIS;
}
/*******************************************************************************
* 函 数 名 : SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_OUT(void)
{
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO32=1; //Output. SDA
EDIS;
}
/*******************************************************************************
* 函 数 名 : SDA_IN
* 函数功能 : SDA输入配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_IN(void)
{
EALLOW;
GpioCtrlRegs.GPBDIR.bit.GPIO32=0; //Input, SDA
EDIS;
}
//void IIC_SDA_SETH()
//{
//
//}
/*******************************************************************************
* 函 数 名 : IIC_Start
* 函数功能 : 产生IIC起始信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA_SETH;
IIC_SCL_SETH;
delay_Xus(5);
IIC_SDA_SETL;//START:when CLK is high,DATA change form high to low
delay_Xus(6);
IIC_SCL_SETL;//钳住I2C总线,准备发送或接收数据
}
/*******************************************************************************
* 函 数 名 : IIC_Stop
* 函数功能 : 产生IIC停止信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL_SETL;
IIC_SDA_SETL;//STOP:when CLK is high DATA change form low to high
IIC_SCL_SETH;
delay_Xus(6);
IIC_SDA_SETH;//发送I2C总线结束信号
delay_Xus(6);
}
/*******************************************************************************
* 函 数 名 : IIC_Wait_Ack
* 函数功能 : 等待应答信号到来
* 输 入 : 无
* 输 出 : 1,接收应答失败
0,接收应答成功
*******************************************************************************/
unsigned char IIC_Wait_Ack(void)
{
unsigned char tempTime=0;
IIC_SDA_SETH;
delay_Xus(1);
SDA_IN(); //SDA设置为输入
IIC_SCL_SETH;
delay_Xus(1);
while(READ_SDA)
{
tempTime++;
if(tempTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_SETL;//时钟输出0
return 0;
}
/*******************************************************************************
* 函 数 名 : IIC_Ack
* 函数功能 : 产生ACK应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Ack(void)
{
IIC_SCL_SETL;
SDA_OUT();
IIC_SDA_SETL;
delay_Xus(2);
IIC_SCL_SETH;
delay_Xus(5);
IIC_SCL_SETL;
}
/*******************************************************************************
* 函 数 名 : IIC_NAck
* 函数功能 : 产生NACK非应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_NAck(void)
{
IIC_SCL_SETL;
SDA_OUT();
IIC_SDA_SETH;
delay_Xus(2);
IIC_SCL_SETH;
delay_Xus(5);
IIC_SCL_SETL;
}
/*******************************************************************************
* 函 数 名 : IIC_Send_Byte
* 函数功能 : IIC发送一个字节
* 输 入 : txd:发送一个字节
* 输 出 : 无
*******************************************************************************/
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t;
SDA_OUT();
IIC_SCL_SETL;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
if((txd&0x80)>0) //0x80 1000 0000
IIC_SDA_SETH;
else
IIC_SDA_SETL;
txd<<=1;
delay_Xus(2); //对TEA5767这三个延时都是必须的
IIC_SCL_SETH;
delay_Xus(2);
IIC_SCL_SETL;
delay_Xus(2);
}
}
/*******************************************************************************
* 函 数 名 : IIC_Read_Byte
* 函数功能 : IIC读一个字节
* 输 入 : ack=1时,发送ACK,ack=0,发送nACK
* 输 出 : 应答或非应答
*******************************************************************************/
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_SETL;
delay_Xus(2);
IIC_SCL_SETH;
receive<<=1;
if(READ_SDA)receive++;
delay_Xus(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
OLED.H文件
#ifndef __IIC_OLED_H
#define __IIC_OLED_H
#include "dsc_config.h"
#define OLED_SIZE_13 1
#define OLED_SIZE_096 0
extern void delay_Xus(Uint16 X);
void IICA_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Send_Byte(unsigned char txd);
unsigned char IIC_Read_Byte(unsigned char ack);
unsigned char IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
extern void OLED_WriteCommand(unsigned char Command);
extern void OLED_WriteData(unsigned char Data);
extern void OLED_Init(void);
extern void OLED_Clear(void);
extern void OLED_ShowCHinese(Uint16 x,Uint16 y,Uint16 no);
extern unsigned int OLED_Pow(unsigned int X, unsigned int Y);
extern void OLED_ShowChar(unsigned char Line, unsigned char Column, char Char);
extern void OLED_ShowString(unsigned char Line, unsigned char Column, char *String);
extern void OLED_ShowNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length);
#endif
超出范围了,字库文件就不上传了。
显示效果