Author Sun Dongmei: Ph.D. and Associate Professor, School of Automation and Electrical Engineering, Nanjing University of Technology

A data collector based on STM32F107 design is designed to realize a variety of data (serial port, CAN port) acquisition and processing, and wireless upload through GPRS module. The CAN device driver was written in detail; the device data was used to upload and download the serial port data of the GPRS module; finally, some problems occurred during the process of using the thread were proposed.

First, functional analysis

The system function is shown in Figure 1, not too complicated. Due to the large amount of data reported by the lower-level sensor module, the content of the writing processing program is large.

Second, the CAN driver is written

In order to modularly process the active reporting data of the sensor, the CAN device no longer uses the previous interrupt processing, but uses the RTT device framework to rewrite the device driver. Study CAN bus transceiver equipment in RTT:

Found only the framework, no content. Just write a candevice like a serial port. Study the serial port driver in use of the component:

This is a process of reading the code. After figuring out the framework, write a driver similar to linux.

After all the above programs have been written, you can use the device general operation function to operate the CAN. In the main program, you first initialize the device and then register the device.

Third, the device mode to achieve serial data processing

The GPRS module is actually used to receive the serial data. First create a gprswatch process to monitor the serial port to receive data.

Void gprswatch ( void ) { rt_thread_t thread ; thread = rt_thread_find ( "gprswatch" ); if ( thread != RT_NULL ) rt_thread_delete ( thread ); /* Create gprswatch thread */ thread = rt_thread_create ( "gprswatch" , gprswatch_entry , RT_NULL , 0x1000 , 0x12 , 200 ); /* The thread is started successfully if created successfully */ if ( thread != RT_NULL ) { rt_thread_startup ( thread ); //rt_thread_delay(RT_TICK_PER_SECOND/2); } }

In the monitoring GPRS serial port thread, after receiving the serial port data, it receives and analyzes and sets the network status.

/ * Monitoring GPRS serial thread inlet * / void gprswatch_entry (void * parameter ) {rt_err_t result = RT_EOK; rt_uint32_t event; unsigned char gprs_rx_buffer [GPRS_RX_LEN] = {0x00}; while (1) {result = rt_event_recv (& rev_event, REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, & event ); if (result == RT_EOK) {if (event & REV_DATA) {rt_memset (gprs_rx_buffer, 0x00, sizeof (gprs_rx_buffer)); rt_thread_delay (RT_TICK_PER_SECOND / 10); rt_device_read (gprs_device, 0, Gprs_rx_buffer , GPRS_RX_LEN ); rt_kprintf ( gprs_rx_buffer ); /* Monitor GPRS module to receive data */ if ( rt_strstr (( char const * ) gprs_rx_buffer , "MYURCCLOSE: 0" )) //network break { net_status = CONNECT_ERROR ; rt_kprintf ( " The network is broken. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " ); } else if ( rt_strstr (( char const * ) gprs_rx_buffer , "Call Ready" )) // Module restart { net_status = CONNECT_NULL ; rt_kprintf ( " The module is restarted. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," + CPIN: NOT READY ")) // card is removed {net_status = CONNECT_ERROR; rt_kprintf (" The card was pulled out. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," $ MYURCACT: 0,0 ")) // network disconnection {net_status = CONNECT_DISCONNECT; rt_kprintf (" Disconnected from the network. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," MYURCREAD: 0 ")) // there is a network data {net_status = CONNECT_GPRSDATAIN;} else if (rt_strstr ((char const *) gprs_rx_buffer," + CMTI: " )) //There is a text message { net_status = CONNECT_MSGDATAIN ; } else { } } if ( event & REV_STOPWATCH ) { return ; } } } }

The monitoring and operation of the corresponding GPRS module is completed elsewhere in the program. A device operation function is also written for the GPRS module read and write operations, mainly using the gprswatch thread previously written:

/ * GPRS module to send and receive * / rt_bool_t gprs_send_data_package (unsigned char * cmd, char * ack, rt_uint32_t waittime, rt_uint8_t retrytime, rt_uint32_t len) {rt_bool_t res = RT_FALSE; rt_err_t result = RT_EOK; rt_uint32_t event; unsigned char gprs_rx_buffer [GPRS_RX_LEN] = {0x00}; rt_thread_t thread; thread = rt_thread_find ( "gprswatch"); if (thread = RT_NULL!) {rt_thread_delete (thread);} do {rt_device_write (gprs_device, 0, cmd, len); result = rt_event_recv (& rev_event , REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, waittime * RT_TICK_PER_SECOND, & event); if (result == RT_EOK) {if (event & REV_DATA) {rt_memset (gprs_rx_buffer, 0x00, sizeof (gprs_rx_buffer)); rt_thread_delay (RT_TICK_PER_SECOND / 2); rt_device_read ( gprs_device , 0 , gprs_rx_buffer , GPRS_RX_LEN ); rt_kprintf ( gprs_rx_buffer ); if ( rt_strstr ( cmd , MSG_IMSI )) // If the IMSI is parsed out of the IMSI data { unsigned char * addr ; addr = rt_strstr (( char const * ) gprs _rx_buffer , "AT+CIMI" ) + 10 ; if ( addr != NULL ) { strncpy ( & imsi [ 0 ], addr , 15 ); rt_kprintf ( " IMSI = :%s " , imsi ); } } if ( rt_strstr ( cmd , MSG_IMEI )) // If the IMEI is parsed out IMEI data { unsigned char * addr ; addr = rt_strstr (( char const * ) gprs_rx_buffer , " \" " ) + 1 ; if ( addr != NULL ) { strncpy ( & imei [ 0 ], addr , 15 ); rt_kprintf ( " IMEI = :%s " , imei ); } } if ( rt_strstr ( cmd , CSQ_CMD )) // If the read CSQ parses out the dbm data { unsigned char csq [ 5 ] = { 0x00 }; unsigned char * addr ; rt_int16_t dbm ; addr = rt_strstr ( (char const *) gprs_rx_buffer, " ,") - 3; rt_strncpy (csq, addr, 3); if (addr = NULL) {dbm = 2 * atoi (csq) - 109;! dbm_data [0] = dbm; dbm_data [ 1 ] = dbm >> 8 ; rt_kprintf ( " DBM = %d " , dbm ); rt_kprintf ( " RSSI = %02x%02x " , dbm_data [ 0 ], dbm_data [ 1 ]); } } if (( rt_strstr ( gprs_rx_buffer , ack )) || ( rt_strstr ( gprs_rx_buffer , "OK" ))) { res = RT_TRUE ; if ( rt_strstr ( cmd , MG323_READ_CMD )) / / If the data command is read, copy the data out { rt_memcpy ( gprs_rx_data , gprs_rx_buffer , GPRS_RX_LEN ); } } else res = RT_FALSE ; } if ( rt_strstr (( char const * ) gprs_rx_buffer , "MYURCREAD: 0" )) //There is network data { net_status = CONNECT_GPRSDATAIN ; rt_kprintf ( " Received network data! " ); } } retrytime -- ; } while (( ! res ) && ( retrytime >= 1 )); gprswatch (); return res ; }

So far, the device operation of the GPRS module has been basically realized.

Fourth, the experience in the debugging process 1. Process initialization and allocate memory

In the RTT project, the int rt_application_init(void) function gives a basic use, dynamically creating the thread rt_thread_create, dynamically allocating memory. In the process of programming, because the memory is too small, you have to divide the allocated memory. The manual recommends using commands to view the memory occupied by the thread during the running of the program, and then divide the memory according to experience. In this way, there are many errors in the debugging process. Later, I flipped through the manual and copied the example to modify the program to create a statically allocated thread. rt_thread_init, the above error no longer appears.

2. Use finsh

Finsh is used extensively during the debugging process, which greatly facilitates debugging.

Refer to the instructions in the user manual: Write a function that can be exported to finsh if it is not running in the program.

In the serial console operation, it is convenient to debug the GPRS related functions, and the above functions need to be run in the main program.

3. The format of the RTT routine

RTT-based STM32F107 platform routines were written and posted on github: https://github.com/sundm75/STM32F107Board-rttproject Each application in the example has a corresponding test**** file. In this file, all used finsh operates in serial port control.

- End -


Ultrasonic Annunciator

Ultrasonic Annunciator,Ultrasonic Piezo Annunciator,Outdoor Ultrasonic Annunciator,Ultrasonic Piezoelectric Annunciator

NINGBO SANCO ELECTRONICS CO., LTD. , https://www.sancobuzzer.com

Posted on