2024-09-01
售卖作品
00

目录

硬件
功能
部分程序
全部程序

硬件

OLED

PCF8591

cpp
/* * OLED * VCC GND * SCL接P2^0 * SDA接P2^1 */ /* * PCF8591 * VCC GND * SCL接P1^4 * SDA接P1^5 */ /* 板子上按键 P1.3 */ /* 单片机ADC输入引脚 P1.1 */ /* 说明:将PCF8591的DAC输出接到单片机ADC输入引脚 P1.1,单片机采集电压并显示 */

功能

这个程序是一个用于嵌入式系统的C语言程序,主要功能是控制一个数字模拟转换器(DAC)输出电压,并通过模数转换器(ADC)采集电压值,同时在OLED显示屏上实时显示这两组电压数据。具体步骤和功能如下:

  1. 初始化: 程序开始时,会停止看门狗定时器(WDT),并根据系统时钟校准常数进行时钟配置,确保系统稳定运行。接着初始化OLED显示屏,并在其上显示字符串"DAC:"和"ADC:"作为标题。

  2. DAC控制:

    • 程序设定一个变量dac_temp来控制输出电压,默认值为0.0。

    • 通过公式dac_value = dac_temp / 3.3 * 255将期望的电压值转换成DAC能识别的数字量,并通过I2C协议写入到地址0x90的设备的0x40寄存器中,实现电压输出控制。

    • 同时,将dac_temp对应的电压值格式化为字符串,并在OLED的第二行显示该电压值。

  3. ADC读取与处理:

    • 配置ADC10(10位模数转换器),开启中断并设置采样时间。

    • 设置P1.3作为按钮输入,启用内部上拉电阻。

    • 主循环中检测按钮状态,如果按钮被按下,则增加dac_temp的值(每次增加0.1V,范围限制在0到3V之间),并更新显示的DAC电压值及实际输出电压。

    • 在主循环中启动ADC采样与转换,进入低功耗模式等待转换完成中断。转换完成后,计算得到的实际电压值(0到3.3V范围内),将其扩大100倍后转换为整数,格式化为字符串,并在OLED的第四行显示ADC采集到的电压值。

综上所述,此程序实现了一个简单的电压控制系统,用户可以通过按钮调节DAC输出电压,并实时查看设置的电压值以及通过ADC采集到的电压反馈值,所有数据显示在连接的OLED显示屏上。

部分程序

cpp
int main( void ) { unsigned char display[10], counta; float volt; int last_volt; int dac_temp = 0.0; uchar dac_value = 0; WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */ if ( CALBC1_8MHZ == 0xFF ) /* If calibration constant erased */ { while ( 1 ) ; /* do not load, trap CPU!! */ } DCOCTL = 0; /* Select lowest DCOx and MODx settings */ BCSCTL1 = CALBC1_8MHZ; /* Set range */ DCOCTL = CALDCO_8MHZ; /* Set DCO step + modulation * / */ OLED_Init(); /* OLED初始化 */ OLED_ShowString( 0, 0, "DAC:" ); OLED_ShowString( 0, 4, "ADC:" ); /* 控制DAC输出电压 */ dac_value = dac_temp / 3.3 * 255; Single_WriteI2C( 0x90, 0x40, dac_value ); /* 地址 寄存器 电压 */ /* DAC输出电压的显示 */ counta = 0; display[counta++] = dac_temp % 100 / 10 + '0'; /* SHI位数字 */ display[counta++] = '.'; display[counta++] = dac_temp % 10 + '0'; /* GE位数字 */ display[counta++] = 'V'; display[counta++] = 0; OLED_ShowString( 0, 2, display ); /* 在第2行显示DAC电压 */ /* P1.1 ADC输入引脚 */ ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; /* ADC10ON, interrupt enabled */ P1DIR &= ~BIT3; /*按键输入引脚寄存器设置 */ P1REN |= BIT3; P1OUT |= BIT3; while ( 1 ) { if ( (P1IN & BIT3) == 0 ) /*按键按下去了 */ { while ( (P1IN & BIT3) == 0 ) ; /*按键按下去了条件一直成立 */ dac_temp = dac_temp + 1; /* 加0.1V */ if ( dac_temp > 30 ) /* 电压大于3V */ { dac_temp = 0; } counta = 0; display[counta++] = dac_temp % 100 / 10 + '0'; /* SHI位数字 */ display[counta++] = '.'; display[counta++] = dac_temp % 10 + '0'; /* GE位数字 */ display[counta++] = 'V'; display[counta++] = 0; OLED_ShowString( 0, 2, display ); /* 在第2行显示DAC电压 */ dac_value = (float) dac_temp / 10 / 3.3 * 255; /* 0到3.3转换到 0到255 传给模块 */ Single_WriteI2C( 0x90, 0x40, dac_value ); /* 地址 寄存器 电压 */ } ADC10CTL0 |= ENC + ADC10SC; /* Sampling and conversion start */ __bis_SR_register( CPUOFF + GIE ); /* LPM0, ADC10_ISR will force exit */ volt = (float) ADC10MEM * 3.3 / 1025; /* 得到电压 0到3.3V */ last_volt = (int) (volt * 100); /* 扩大100倍 */ counta = 0; display[counta++] = last_volt / 100 + '0'; /* 百位数字 */ display[counta++] = '.'; display[counta++] = last_volt % 100 / 10 + '0'; /* 十位数字 */ display[counta++] = last_volt % 10 + '0'; /* 个位数字 */ display[counta++] = 'V'; display[counta++] = 0; OLED_ShowString( 0, 6, display ); /* 在第4行显示ADC采集到的电压 */ } }

全部程序

cpp
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2

在这里插入图片描述

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!