Digital tube drive circuit: Charlie multiplexing method
8 IOs drive an 8-bit 7-segment digital tube, and the circuit is very similar to the key-conflict-free circuit of most mechanical keyboards . So the names are consistent.
The digital tube is integrated on the PCB, and the light transmission is softened through 3D printing parts, and the integrated display of the shell is more beautiful.
In the later stage, we tried to transplant the program of foot-to-foot compatible chip. At present, we first developed the sponsor of this event: Hangshun HK32F030M.
Let’s complain about the location of the programming port and the multiplexing of hardware I2C. You cannot use I2C while debugging.
This is the schematic diagram of using 3 ios to drive 6 LEDs using Charlie multiplexing method.
Assume that P1 is high, P3 is low, and P2 is high resistance. LED6 is on at this time. Although LED1 and LED3 have forward voltage in series, due to the clamping of LED6, the voltage is not enough to turn on at the same time.
If P1 is high, P2 and P3 are both low, then both LED1 and LED6 are on, but the brightness is not as bright as the above state, because the current of both LEDs flows through the P3 resistor, and the voltage division of the P3 resistor increases.
Therefore, a diode is connected in parallel to each current-limiting resistor, and the one-way conductivity is used to make the voltage division at both ends of the resistor consistent in a specific current direction, so that the LEDs that light up at the same time have the same brightness.
It’s not that my code is not open source, but that the code is released, even if 100 people download it. However, 80 people couldn't understand it.
Then I might as well just list the special algorithms and explain them with pictures and texts so that more people can understand them.
You can take a look at the power supply project of my GD32 cup . Although the final function was not successful, it was often collected and cloned by people every now and then, but no one liked it [PS: You should like all three. Your support is my motivation for updating]. If you have anything you want to see about the algorithm, please mention it in the comments section. I will update later when I have time.
According to the technical documentation, the effective accuracy of the ADC of HK32F030M is 8 bits. If the temperature is to be displayed to 1 digit after the decimal point, an ADC of at least 12 bits is required.
What to do about this?
At this time, supersampling technology can be used.
In the first step, the ADC is set to continuous conversion, and the EOC conversion is completed and interrupted.
void ADC_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_ADC_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GOIO_ADC_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(GOIO_ADC_PORT,GPIO_PinSource6,GPIO_AF_7);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC ,ENABLE);
ADC_DeInit(ADC1);
ADC_StructInit(&ADC_InitStructure);
ADC_ClockModeConfig(ADC1,ADC_ClockMode_SynClkDiv4);//系统时钟4分频,8M
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//开启连续转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;//向后扫描
ADC_Init(ADC1,&ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_239_5Cycles);
/* Enable EOC interrupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);//转换结束中断使能
/* Configure and enable ADC1 interrupt */
NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ADC_GetCalibrationFactor(ADC1);//ADC校准
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
ADC_StartOfConversion(ADC1);
}
The second step is to accumulate the values read back by the ADC in the interrupt (since the average is required later, it is better to add it up first).
Here, since the keys and the thermistor share the same ADC, in order to ensure normal key scanning, the refresh rate is set to a number slightly larger than 1000Hz.
extern uint16_t ntc_data_13b[2];
void ADC1_COMP_IRQHandler(void)
{
static uint8_t i=0;
if(ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET)
{
ntc_data_13b[0]+=ADC_GetConversionValue(ADC1)>>4;//读取后自动清除EOC标志位
i++;
if(i>=32)//32分频,1041.6Hz
{
i=0;
ntc_data_13b[1]=ntc_data_13b[0];//存入二缓
ntc_data_13b[0]=0;//一缓清零
}
}
}
There are a lot of animation special effects. Here is a simpler one, using downward movement as an example.
The picture above shows the process of moving down. There is only one step to extract the repeated parts (the same goes for moving up).
#define digital_a 0x01
#define digital_b 0x02
#define digital_c 0x04
#define digital_d 0x08
#define digital_e 0x10
#define digital_f 0x20
#define digital_g 0x40
uint8_t digital_putdown(uint8_t dat)
{
uint8_t temp=0;
temp|=(dat&digital_g)?digital_d:0;//G赋值到D
temp|=(dat&digital_a)?digital_g:0;//A赋值到G
temp|=(dat&digital_b)?digital_c:0;//B赋值到C
temp|=(dat&digital_f)?digital_e:0;//F赋值到E
return temp;//其余没赋值的数据丢弃
}
First of all, many people have given inaccurate feedback on this DS1302. In fact, there is a trick:
You can refer to this website: http://www.51hei.com/bbs/dpj-177015-1.html
The code below adjusts the time.
//输入最小数值-86400
void time_adjust(int32_t sec)
{
uint8_t time_temp[7];
uint8_t i;
for(i=0;i<7;i++)
time_temp[i]=bcd2hex(*((uint8_t *)&time_data+i));
if(sec<0)//直接借一天做减法
{
sec+=86400;
time_temp[5]--;//星期是从1到7,不担心溢出
}
time_temp[0]+=sec%60;
if(time_temp[0]>=60)
{
time_temp[1]+=time_temp[0]/60;
time_temp[0]%=60;
}
time_temp[1]+=sec%3600/60;
if(time_temp[1]>=60)
{
time_temp[2]+=time_temp[1]/60;
time_temp[1]%=60;
}
time_temp[2]+=sec/3600;
if(time_temp[2]>=24)
{
time_temp[5]+=time_temp[2]/24;
time_temp[2]%=24;
time_temp[5]%=7;
time_temp[5]=time_temp[5]?time_temp[5]:7;//将零偏移到7
}
for(i=0;i<7;i++)
*((uint8_t *)&time_data+i)=hex2bcd(time_temp[i]);
}
Since I don’t have year, month and day here, only week, it’s a little easier. There is no need to consider more bases.
As in the above website, choose a quiet time at night to calibrate. Of course, there is a chance that the alarm will be skipped during calibration. But who would set the midnight bell?
All reference designs on this site are sourced from major semiconductor manufacturers or collected online for learning and research. The copyright belongs to the semiconductor manufacturer or the original author. If you believe that the reference design of this site infringes upon your relevant rights and interests, please send us a rights notice. As a neutral platform service provider, we will take measures to delete the relevant content in accordance with relevant laws after receiving the relevant notice from the rights holder. Please send relevant notifications to email: bbs_service@eeworld.com.cn.
It is your responsibility to test the circuit yourself and determine its suitability for you. EEWorld will not be liable for direct, indirect, special, incidental, consequential or punitive damages arising from any cause or anything connected to any reference design used.
Supported by EEWorld Datasheet