As we all know, I bought a remote control yesterday - > Full solution of Tiny X8M remote control , the article is here. But this is open source. The code is well written. It's a pity not to read it. Read it.
There are two sets of protocols, 8D and 16D. Let's look at 8D first.
There is also the STM8 standard library. Decompile it here and use it.
Create a doc folder
hh -decompile ./doc ./stm8l15x-16x-05x_al31-l_stdperiph_drivers_um.chm
ok
There is a Chinese manual
Here are the files in the menu folder,
The first program is to calibrate the remote control. You need to know your maximum value and your minimum value. The rest is a range of mapping.
The remote control is not always in a proper running state after it is turned on. It may be in various states. As shown in the figure, it may be that the time is too long, the rocker of the remote control does not return after power on, or the power is not enough, and the middle position is not in the middle position, or the wireless module is broken.
After power on, see what state the remote control should be in
y=( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 39, 39, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96, 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 118, 120, 121, 123, 124, 126, 127, 128, 130, 131, 133, 134, 135, 137, 138, 140, 141, 143, 144, 146, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 162, 164, 165, 165, 167, 168, 170, 171, 173, 174, 176, 177, 179, 180, 182, 183, 185, 186, 188, 189, 191, 192, 194, 195, 197, 198, 200, 201, 203, 204, 206, 207, 209, 210, 212, 213, 215, 216, 218, 219, 221, 222, 224, 225, 227, 228, 230, 231, 233, 234, 236, 237, 239, 241, 242, 244, 245, 247, 248, 250, 251, 253, 254, 256, 257, 259, 260, 262, 263, 265, 266, 268, 269, 271, 272, 274, 275, 277, 278, 280, 281, 283, 284, 286, 287, 289, 290, 292, 293, 295, 296, 298, 299, 301, 302, 304, 305, 307, 308, 310, 311, 313, 314, 316, 318, 319, 321, 322, 324, 325, 327, 328, 330, 331, 333, 334, 336, 337, 339, 340, 342, 343, 345, 346, 348, 349, 351, 352, 354, 355, 357, 358, 360, 361, 363, 364, 366, 367, 369, 370, 372, 373, 375, 376, 378, 379, 381, 382, 384, 385, 387, 388, 390, 392, 393, 395, 396, 398, 399, 401, 402, 404, 405, 407, 408, 410, 411, 413, 414, 416, 417, 419, 420, 420 );
The throttle curve can be drawn by yourself. Note that it is a 1x420 array
startUp is a bit like an initialization method
This is a section of the code about rocker acquisition and transmission
This is all the methods in this package
In fact, I should continue to read it, but I think the source code of this menu is very interesting. I decided to stay here.
These all introduce a header file called include
VSCodeF12 opens the definition of our header file
In fact, you can see that the spaces in this place are meaningful. At the beginning, they communicate with the underlying hardware, and in the middle are the peripheral sensors, LED, beep and key of the remote control, which are like drivers. The second is the encapsulation of RF chip and transmitter protocol.
Finally, this is what I just wrote above. It is some main processing logic.
Enter the extreme value calibration method: press and hold ch6 (lower) + right five-dimensional key (Enter) to power on to enter the extreme value calibration
--------------------------------------------------------------------------------
Factory calibration:
(1) Calibrate the median value of Rud, air and ELE rocker (take 10 effective values, remove the maximum and minimum values, and then calculate the average)
(2) Calibrate the maximum and minimum values of Rud, THR, air and ELE rocker (take 10 effective values, remove the maximum and minimum values, and then calculate the average)
Because this extreme data is not friendly to our average, this place needs to be subtracted
I haven't written the code yet.
Power on detection:
(1) Detect the reverse dial switch position.
(2) Whether it is necessary to enter factory calibration mode.
*******************************************************************************/
After turning on the power, it should start running from here. If not, it is the second one to start running.
C program, find the main file first:
Turn off the interrupt, call the boot method (this is not the startup method), and turn on the interrupt
Then the watchdog initializes
These are our own methods
The code here is written in water, which directly delays the nop and does not install 13 at all
Then call the delay function above, and then start the initialization of a bunch of things below
I'll see if it's necessary
It turns out to be:
ADC initializes our pin first
This is our STM8 DMA method
Channel 0 is turned on
The next function is to call this initialization method, which is combined with the above
The data of peripherals is directly sent back to the memory. There is no need to interrupt the CPU frequently. The CPU will never say that it is boring!!!
DMA sending function, check whether the parameters are correct, and then select the enabled channel or turn it off. This is not written very well.
This function is a bit like a global function, in charge of life and death.
Turn off the internal ADC reference voltage
This is the setting of ADC
Channel configuration function, see for yourself
Here's how to use it
Eight channels are arranged
Do you remember using DMA on it? It comes in handy here
First map and then open. In fact, I think it's like forwarding
#define ADC1 ((ADC_TypeDef *) ADC1_BASE)
This is the underlying implementation of ADC1
Stupid? What I wrote is not ignorant. What are you ignorant of? continue
Look at this, gee, serial lighting? I wonder directly???
At the beginning, I defined some macro variables, which obviously means. That's all
coming!
#define CLK ((CLK_TypeDef *) CLK_BASE)
Clock peripheral base address
Then there is our clock configuration
Serial port initialization
#define USART1 ((USART_TypeDef *)USART1_BASE)
USART_DeInit(USART1);
Serial port 1 is used
I don't quite understand the details of some parameter settings of the serial port. I'll come back after I learn it for a few days
Let's see the serial port together. I won't see it when I meet it in the future.
This is a bit like a simple Yazi who has realized his own agreement
8-bit data is transmitted through USART peripherals.
The final light is the state of the light
The light flashes here
uint8_t LED_Status_SendDat = 0;
Then this LED is an 8-bit unsigned variable
This is what comments say. If it is invalid, keep your state.
Here is our battery power
BB ring
Using timer drive
There's nothing to say. Operate the timer
Look what it's called, short call
Long cry
Call twice
Give me a long cry
This is a little funny....
continue
What does the key include
Look at the initialization of the keys
This is the dial switch
Japanese and American hands need hard modification
Initialization of serial port 3. Note that the DMA channel of UART3 is opened here
EEPROM, use again, store things
This is clearly the initialization of D8 protocol. I don't know why D16 is written???
There are too many interrupts, so we need to simply control the timing of interrupt sending
!!! See, you have finished so much work in the moment of power on!!!
And this is just a boot () method...
Of course, the watchdog also needs to be initialized. The running and flying program is saved
volatile bool tbc_2ms_flag = false; //Note: this may not be the true accurate 2mS
2ms time
#define FeedTheDog()
feed a dog
If 2ms arrives, feed the dog (I may be a little confused here)
Then the menu method jumps in
Seeing this, serial port 3 transmits data. No wonder DMA is used. It turns out to be of great use!
This sending function is very long. Open it
In this way, it will be much better. Please write it later during the specific sending period
After that, use this function to send it out
#define DMA1_Channel1 ((DMA_Channel_TypeDef *)DMA1_Channel1_BASE)
Channel here
Reset of ADC channel
Barking BB
Key scanning, there are functions below, so I won't take a screenshot
I was studying when I read it
I don't know what you think after reading these two, or I don't know if you understand them
Within 2ms, the single chip microcomputer is comparing the time, the watchdog is eyeing, the internal ADC is constantly reset and AD conversion, and then the status has to be sent to BB to decide whether to ring. LED s and buttons, not to mention, are running all the time. They have to pack data all the time and send it to the CC2500 chip through DMA channel via serial port 3 (am I wrong).
Come on, if you're not tired, keep playing with me~
Looking at this code, we have understood that menu is indeed the most important method in the main method. Here, it is OK to use process, that is, menu originally means menu, but it is actually an organizational framework.
The machine will select one of these states.
After power on, check the setting of the dial switch
Let's make a 0 and 1 for the Japanese and American players first
Use here
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
The situation of this IO port is being set. It needs to be short circuited
Then here is, look at the instructions below...
Such a son...
Then wait a minute
Press the key combination to enter the calibration or debug mode
Here is the setting of GPIO
ad locum
#define GPIOA_BASE (uint16_t)0x5000
This is the underlying base address of GPIOA
Use the and and IDR operation once to change the corresponding bit
It's calculated here. It's the structure above
Dial switch here
A little dazed... No, I'll write it tomorrow.