Complete the digital tube step by step
main content:
Step 1: Generate a 1ms time base
Step 2: Static Display
Step 3: Dynamic Scanning
Step 4: Afterglow and Ghosting
Step 5: Task function with message mechanism
Step 6: Display in the specified base
-------------------------------------------------------------------------------------------------------------------------------------
Development environment: AVR Studio 4.19 + avr-toolchain-installer-3.4.1.1195-win32.win32.x86
Chip model: ATmega16
Chip frequency: 8MHz
-------------------------------------------------------------------------------------------------------------------------------------
Step 1: Generate a 1ms time base
illustrate:
1. Use the CTC interrupt of timer 0 to generate a 1ms time base signal. In CTC mode, the initial value is automatically reloaded, which is more convenient.
2. Use OCF0 interrupt and do not need OC0 pin to output waveform.
Code:
Relevant definitions in Drv_Timer.h:
// -------------------
// Timer interrupt mode
typedef enum
{
INT_MODE_TOV = 0,
INT_MODE_OCF = 1,
INT_MODE_ICF = 2,
INT_MODE_OCF1A = 3,
INT_MODE_OCF1B = 4
} TIMER_INT_MODE;
//Timer compare match pin output mode
typedef enum
{
COM_MODE_NONE = 0,
COM_MODE_TOGGLE = 1,
COM_MODE_CLEAR = 2,
COM_MODE_SET = 3,
} TIMER_COM_MODE;
// Timer 0
typedef enum
{
T0_WGM_NOMAL = 0,
T0_WGM_PHASE_PWM = 1,
T0_WGM_CTC = 2,
T0_WGM_FAST_PWM = 3,
T0_CLK_SOURCE_NONE = 0,
T0_CLK_SOURCE_CLK_1 = 1,
T0_CLK_SOURCE_CLK_8 = 2,
T0_CLK_SOURCE_CLK_64 = 3,
T0_CLK_SOURCE_CLK_256 = 4,
T0_CLK_SOURCE_CLK_1024 = 5,
T0_CLK_SOURCE_T0_FALL = 6,
T0_CLK_SOURCE_T0_RAISE = 7
} TIMER0_MODE;
Operation function in Drv_Timer.c:
// ==========================================================================================================
//TIMER0 initialization
//
// Parameter: wave_mode working mode/waveform generation mode selection
// OC_mode compare match/PWM output mode selection
// clk_source clock source and prescaler selection
//
// When writing TCCR0, you need to clear bit7=FOC0
//
// Timer overflow period T = ((1.0 / 8000000) * 1000000) * clk_source * 256 ( @ 8MHz )
// ==========================================================================================================
void Drv_Timer0_init(const uint8_t wave_mode, const uint8_t com_mode, const uint8_t clk_source)
{
uint8_t wgm00,wgm01;
wgm00 = wave_mode & 0x01;
wgm01 = (wave_mode & 0x02) >> 1;
// When writing TCCR0, you need to clear bit7=FOC0 to 0
TCCR0 = (wgm00 << 6)| // Operation mode/waveform generation mode selection
(wgm01 << 3)|
((com_mode & 0x03) << 4)| // Compare match/PWM output mode selection
((clk_source & 0x07) << 0); // Clock source and prescaler selection
}
// ==========================================================================================================
//TIMER0 interrupt enable
//
// Parameter: int_mode = INT_MODE_TOV or INT_MODE_OCF or INT_MODE_ICF
// enable = ENABLE 或 DISABLE
//
// illustrate:
// 1. OC0 pin must first be configured as a compare match pin, and then modify the data direction register DDB3
// 2. You can enable/disable interrupts of a mode separately
//
// ==========================================================================================================
void Drv_Timer0_INT_Enable(const uint8_t int_mode, const uint8_t enable)
{
if(INT_MODE_TOV == int_mode)
{
if(DISABLE == enable)
{
TIMSK &= ~(1 << TOIE0);
}
else
{
TIMSK |= (1 << TOIE0);
}
TIFR |= (1 << TOV0);
return ;
}
if(INT_MODE_OCF == int_mode)
{
if(DISABLE == enable)
{
TIMSK &= ~(1 << OCIE0);
}
else
{
TIMSK |= (1 << OCIE0);
}
TIFR |= (1 << OCF0);
}
}
// ==========================================================================================================
// Set the values of TCNT0 and OCR0
//
// (1). Under compare match, OCR0 needs to be set after TCNT0 is set
// ==========================================================================================================
void Drv_Timer0_set_TCNT0_OCR0(const uint8_t tcnt0, const uint8_t ocr0)
{
TCNT0 = tcnt0;
OCR0 = ocr0;
}
Set timer 0 in sys_timer.c and use PA1 to test the timing in OCF0 interrupt:
#include #include "Drv_Timer.h" #include "sys_timer.h" // ========================================================================================================== // System task timer // // (1). Use Timer0 to generate a 1ms time stamp // Timing period T = ((1.0/8000000)*1000000)*64*(124+1) = 1000us = 1ms // // ========================================================================================================== void sys_timer_init(void) { // Timer 0 initialization: CTC mode, OC0 pin not connected, 64 prescaler Drv_Timer0_init(T0_WGM_CTC, COM_MODE_NONE, T0_CLK_SOURCE_CLK_64); // Set initial values: TCNT0=0, OCR0=122 Drv_Timer0_set_TCNT0_OCR0(0, 122); // Enable OCF0 interrupt Drv_Timer0_INT_Enable(INT_MODE_OCF, ENABLE); } // ========================================================================================================== // System timer interrupt // // (1). Use Timer0's CTC interrupt to schedule each task // // ========================================================================================================== ISR(TIMER0_COMP_vect) { PORTA ^= (1 << PA1); // Use PA1 to test the timing period } Initialization is completed in main.c, and IO is set: // ========================================================================================================== // Main function // ========================================================================================================== #include #include "Drv_Timer.h" #include "system.h" #include "sys_timer.h" #include "config.h" // ========================================================================================================== //main function // ========================================================================================================== int main(void) { // --------- // Turn off global interrupts cli(); // System initialization (including sys_timer_init()) sys_init(); DDRA |= (1 << DDA0) | (1 << DDA1); PORTA &= ~((1 << PA0 ) | (1 << PA1 )); // OC0/PB3 is initialized to output 0 DDRB |= (1 << DDB3); PORTB &= ~((1 << PB3 )); // Enable global interrupt be(); // --------- while(1) { } return 0; } Test Results: The oscilloscope output is as follows: 1. The PA1 pin outputs a square wave with a period of 2*1.0ms, and the pin level flips every 1.0ms. Use OCR0=124 and calculate to get an exact 1.0ms, but it takes time to enter the interrupt function. So here we use a slightly smaller OCR0=122, so that the time from interrupt generation to entering the interrupt function is more accurate to 1.0ms Some timing functions will accumulate time base errors, and the accumulated errors will become larger as time goes by, so try to be as precise as possible here. At this point, the 1.0ms timing is completed. 2. The OC0 pin has no waveform output, and we do not need to use this pin, so let it maintain the characteristics of ordinary IO. ------------------------------------------------------------------------------------------------------------------------------------- Step 2: Static Display illustrate: 1. This step requires displaying the specified symbol on the specified digital tube according to the circuit diagram. 1. Digital tube drive circuit diagram: The circuit uses a common cathode digital tube: A digital tube has 8 LEDs, which is called an 8-segment digital tube. Common cathode means: 1. The negative poles of the 8 LEDs are connected to the com pin 2. The positive poles of the 8 LEDs correspond to 8 pins, numbered [Dp, g, f, e, d, c, b, a] The voltage and current of the digital tube: The current required to light up one digital tube can be found by looking up the digital tube data sheet provided by the manufacturer. If there is no data sheet, you can estimate it to be 10-20mA and the voltage to be 2V. Like ordinary LEDs, current limiting resistors need to be added when necessary. In dynamic scanning, each digital tube is lit for a few milliseconds and off for tens of milliseconds, not lit all the time, so it is okay not to add a current limiting resistor, unless it is a high-current digital tube. The driver chips of the digital tubes are 74HC138 and 74HC573, and their driving current is enough to light up one digital tube: 2. Lighting method of common cathode digital tube: 1. Input a high level at pin a, input a low level at pin b-Dp, and input a low level at com pin. Then, segment [a] is lit, and segments [Dp,g,f,e,d,c,b] are not lit. That is, only the segments whose input state is high will be lit. 2. Input high level at pins b and c, input low level at pins a and d-Dp, and input low level at com pin. Then, segment [b,c] is lit, and segments [a,d,e,f,g,Dp] are not lit. The image obtained at this time is the image of the number '1', and the corresponding segment code [Dp,g,f,e,d,c,b,a]=0b00000110=0x06. 3. Input high level at pins a, b, g, e, and d, input low level at pins c, f, and Dp, and input low level at the com pin. Then, segments [a,b,g,e,d] are lit, and segments [c,f,Dp] are not lit. The image obtained at this time is the image of the number '2', and the corresponding segment code [Dp,g,f,e,d,c,b,a]=0b01011011=0x5B. 4. That is to say, the digital tube with low level at com port is enabled, and if there is a segment not equal to 0 in its segment selection, this segment will be lit. 3. Segment code: 1. The segment codes of 16 hexadecimal digits [0-9, AF] are as follows: static const uint8_t segment_code[17]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, // 0 - 9
Previous article:Atmega16 - BSP and Task List
Next article:A005-Software Structure-From Frontend and Backend to Scheduler
Recommended ReadingLatest update time:2024-11-17 09:36
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- ESP8266EX——Knowledge Sharing on Clock and RF
- Virtual static random access memory in mobile and portable applications
- Fatal Error[Pe1696]: cannot open source file "stm8s.h"
- 【NXP Rapid IoT Review】+8. Brief summary
- Does anyone have the engineering source code that can run on Chuanglong 6678 nor-writer?
- [GD32F350 Development Sharing 7] GPIO Simulation I2C Driver
- Why do we write =0 when assigning a variable a value of 0, but write =0xffffffffu when assigning it a value of 0xffffffff?
- Learning PCB
- TMDSLCDK138 board about PRU part program
- NI Taobao brand store, Double Eleven hot items return