【Start_DSC28034PNT湖人开发板免费体验】中科昊芯Start_DSC28034PNT ADC采样+OLED显示 - RISC-V MCU技术社区 - 电子技术william hill官网 - 广受欢迎的专业电子william hill官网 - 威廉希尔官方网站
分享 收藏 返回

[文章]

【Start_DSC28034PNT湖人开发板免费体验】中科昊芯Start_DSC28034PNT ADC采样+OLED显示

本次测试目的为了测试板子的ADC功能,并将检测结果通过OLED显示出来。

一、硬件连接

通过原理图,找到A0引脚,将A0与信号发生器接通,注意电压不要超过3.3,通过OLED观察ADC采集值。
1.jpg
二,程序编写
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();  //Initializes the System Control registers to a known state.
	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;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM

    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);

//IIC所有操作函数(驱动程序)
void IICA_Init(void);                //初始化IIC的IO口
void IIC_Start(void);               //发送IIC开始信号
void IIC_Stop(void);                //发送IIC停止信号
void IIC_Send_Byte(unsigned char txd);          //IIC发送一个字节
unsigned char IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
unsigned char IIC_Wait_Ack(void);               //IIC等待ACK信号
void IIC_Ack(void);                 //IIC发送ACK信号
void IIC_NAck(void);                //IIC不发送ACK信号
//OLED通讯程序
extern void OLED_WriteCommand(unsigned char Command);//OLED写命令
extern void OLED_WriteData(unsigned char Data);//OLED写数据

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

超出范围了,字库文件就不上传了。

显示效果
2.jpg
3.jpg

更多回帖

×
发帖