1.MCP4017原理
这是一种可以通过I2C来设置接入电阻值的器件,可以作为滑动变阻器,也可以作为电位器(分压器)。
板子上的就是变阻器:
电路网络如下:
结合两图,B直接接到了GND,W则连接电阻R17(10K)之后连接VCC,从B到W之间的就是串联的电阻。我们通过I2C发送数据字节(00h~7Fh)来选择闭合哪一个开关,闭合N号开关即串联接入N个电阻。
2. 计算
下图红框是板子上MCP4017的的Rs值和RAB总阻值:
那么计算公式如下图:
那么PB14的电压如何计算?
分压公式:
还有一种方法:使用ADC1进行测量,如果遇到ADC1有两个通道的话,用DMA,使用二维数组存储数据。
3.代码
时序你主要看上图的I2C总线那一行,对于写操作,两个应答都是来自于器件的应答,不同的是读操作在主器件收到数据后要回应不应答,然后结束。具体代码如下:
MCP4017代码:
void MCP4017_Write(uint8_t value)
{
I2CStart();
I2CSendByte(0X5E);//0101 1110 写
while(I2CWaitAck());
I2CSendByte(value);
while(I2CWaitAck());
I2CStop();
}
uint8_t MCP4017_Read()
{
uint8_t val;
I2CStart();
I2CSendByte(0X5F);//0101 1111 READ
while(I2CWaitAck());
val=I2CReceiveByte();
I2CSendNotAck();
I2CStop();
return val;
}
两个器件的测试函数以及相关变量:
//*LCD显示专用变量
unsigned char Lcd_Disp_String[21];//最多显示20个字符
//*EEPROM的相关变量
unsigned char EEPROM_Sendbuf[11]={1,2,3,4,5,4,3,2,1,9};
unsigned char EEPROM_Recbuf[11];
//MCP4017
uint8_t RES_4017;
void EEPROM_Test()
{
EEPROM_Write(EEPROM_Sendbuf,0,10);
HAL_Delay(10);
EEPROM_Read(EEPROM_Recbuf,0,10);
}
void MCP4017_Test()
{
MCP4017_Write(0X3F);
RES_4017=MCP4017_Read();
}
另给出LCD的显示测试:
void Lcd_Proc(void)
{
sprintf((char *)Lcd_Disp_String, "EE:%d%x%x%x%x%x%x%x%x%x",EEPROM_Recbuf[0],EEPROM_Recbuf[1],EEPROM_Recbuf[2],EEPROM_Recbuf[3],EEPROM_Recbuf[4],EEPROM_Recbuf[5],EEPROM_Recbuf[6],EEPROM_Recbuf[7],EEPROM_Recbuf[8],EEPROM_Recbuf[9]);
LCD_DisplayStringLine(Line0, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, "RES_K:%5.2fK",0.7874*RES_4017);
LCD_DisplayStringLine(Line1, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, "PB14V:%6.3fV",3.3*((0.7874*RES_4017)/(0.7874*RES_4017+10)));
LCD_DisplayStringLine(Line2, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, "ADC_PB14V:%2.2fV",ADC1_Value());
LCD_DisplayStringLine(Line3, Lcd_Disp_String);
HAL_RTC_GetTime(&hrtc, &H_M_S_Time, RTC_FORMAT_BIN);//读取日期和时间必须同时使用
HAL_RTC_GetDate(&hrtc, &Y_M_D_Date, RTC_FORMAT_BIN);
sprintf((char *)Lcd_Disp_String, "Time:%02d-%02d-%02d",(unsigned int)H_M_S_Time.Hours,(unsigned int)H_M_S_Time.Minutes,(unsigned int)H_M_S_Time.Seconds);
LCD_DisplayStringLine(Line4, Lcd_Disp_String);
sprintf((char *)Lcd_Disp_String, "Date:%02d-%02d-%02d-%02d",(unsigned int)Y_M_D_Date.Year,(unsigned int)Y_M_D_Date.Month,(unsigned int)Y_M_D_Date.Date,(unsigned int)Y_M_D_Date.WeekDay);
LCD_DisplayStringLine(Line5, Lcd_Disp_String);
}