The eighth chapter is to understand AMetal in depth . The content of this article is 8.2 HC595 interface.
8.2 HC595 interface
The HC595 is a “serial-to-parallel†peripheral that allows data to be output via the GPIO control data pins and clock pins. However, in some MCUs with SPI peripherals, the SPI is often used to control the HC595 output to make the driver simpler. In order to shield the difference of the underlying data output mode, the relevant interface of the HC595 can be defined according to the design method of the LED universal interface.
> > > 8.2.1 Defining interfaces
1. Interface naming
Since the object of operation is HC595, the interface name is prefixed with "am_hc595_". The basic operation of the HC595 is to output parallel data with the corresponding interface name:
Am_hc595_send
In particular, the output of the HC595 is a three-state output that is controlled by the OE pin, so the corresponding interface enable output (normal output data) or disable output (high-impedance state) can be defined. Its corresponding interface name is:
Am_hc595_enable
Am_hc595_disable
2. Interface parameter
In the design of the LED universal interface, there may be multiple LEDs, so the unique ID number led_id is used to distinguish multiple LEDs. According to this logic, is it also necessary to use hc595_id to distinguish between different HC595s?
In the LED universal interface, the ID number is used to distinguish different LEDs. This requires the conversion between the led_id and the corresponding LED device in the interface implementation, that is, the corresponding LED device is searched by the ID number. Obviously, as LED devices increase, search time will increase. Using ID numbers to distinguish between different LEDs, although simple and easy to understand, is not efficient.
For operating LEDs, they are usually in the order of seconds and do not operate the LEDs at very fast rates. If the LED changes too fast, it is meaningless that the naked eye cannot observe the corresponding phenomenon. Therefore, the impact of search time consumption is negligible for LEDs. Although the specific device of the HC595 output control is uncertain, as a general-purpose output device, the output efficiency should be as high as possible. Do not affect the output efficiency due to the strategy of the driver implementation. For example, the common GPIO can output at a rate of MHz. This change is of the us level. Obviously, the search time will have a certain impact on the output efficiency.
In order to achieve fast output, it is best not to have any search process, directly operate the corresponding HC595 object to achieve output. In this case, using a pointer to the object is a good solution, as long as you have a pointer to the object, you can directly use the method provided by the object.
Obviously, using pointers to objects is just to improve the efficiency of the interface implementation, and is not directly related to the user. For the user, it does not need to care about the specific type of this pointer. In order to shield the user from the concept of "pointers", you can define a separate type for the pointer, which is the "handle" concept often mentioned in this book. Since the pointer type of the HC595 object is not yet known, you can first define an untyped pointer type as the handle type. such as:
A handle of this type is essentially a pointer to an HC595 object, which itself represents an HC595 object identified in the system. Based on this, all interfaces use this type as the first parameter, namely:
Am_hc595_enable (am_hc595_handle_t handle);
Am_hc595_disable (am_hc595_handle_t handle);
Am_hc595_send (am_hc595_handle_t handle);
In particular, for am_hc595_send(), you also need to specify the data to be sent using parameters, often using a pointer to the data's first address and the number of bytes of data to represent a piece of data. You can add two parameters to am_hc595_send():
Am_hc595_send (am_hc595_handle_t handle, const void *p_data, size_t nbytes) ;
Where p_data points to the first address of the data, using the void * type, which can point to the first address of any data type, using the const modifier, indicating that this interface is only used to send data, does not change the data content; nbytes specifies the sending The number of bytes of data, if there is only a single HC595, the output is a single byte (8 bits). If there are multiple HC595 cascades, the output is n bytes (n is the number of HC595, total 8 × n bits ).
In practice, a single HC595 can only output 8 bits of data. In order to output more bits of data, multiple HC595s can be cascaded in a cascade manner. Therefore, the HC595 device represented by the HC595 "handle" here may contain multiple cascaded HC595s to achieve multi-bit data output.
3. return value
The interface has no special description, and directly defines the return value of all interfaces as the standard error number of type int. Based on this, the complete definition of the HC595 interface is detailed in Table 8.4. The corresponding class diagram is shown in Figure 8.5.
Table 8.4 HC595 Universal Interface (am_hc595.h)
Figure 8.5 Class diagram corresponding to HC595
In particular, the am_hc595_handle_t type in the current interface is a void * type, and finally, it needs to be a pointer type to the object. As the following describes the implementation of the interface, the corresponding device type is defined, and the specific definition is updated at that time.
> > > 8.2.2 Implementing the interface
1. Abstract HC595 device class
Similar to the implementation of the LED universal interface, in order to shield the underlying implementation differences, some functions related to the underlying hardware can be abstracted. According to the three interfaces, the corresponding three abstract methods can be defined and stored in a virtual function. In the table. which is:
Similarly, the abstract method and p_cookie are defined together, which is the abstract HC595 device. such as:
Obviously, the specific HC595 device is derived directly from the abstract HC595 device, and then the specific HC595 device implements three abstract methods based on the actual hardware.
Compared with the definition of the abstract LED device, it can be found that the method for defining the abstract device and the method for defining the abstract LED device are completely identical, and this method can be used as a template for defining an abstract device, namely: first, according to the interface Definition, collation requires specific devices to implement those functions, and then abstract these functions into methods, and store them in a virtual function table, the first parameter of these abstract methods are p_cookie. Finally, the virtual function table and p_cookie are integrated into a new structure, which is the abstract device type. The pseudo code is detailed in Listing 8.18.
Listing 8.18 General method of abstract device definition
In pseudo code, [name] indicates the specific name of the current module, such as led. Of course, if needed, you can add other required members to the abstract preparation, such as LED devices, which use a linked list to manage multiple LED devices, and therefore have p_next pointer members.
In the HC595 interface, handle is used as the first parameter, which is essentially a pointer to the device. Since all specific devices are derived from the abstract HC595 device, the type of the handle can be defined as:
In this way, the implementation of all interfaces can directly call the abstract method implementation, and the specific implementation of the abstract method is completed by the specific HC595 device. The implementation of each HC595 interface is detailed in Listing 8.19.
Listing 8.19 HC595 Interface Implementation
Since the handle is a pointer directly to the device, the corresponding method can be directly found through the handle. Therefore, during the implementation of the entire interface, there is no query search process, and the efficiency is high. In addition, when the handle directly points to the device, there is no need to centrally manage each HC595 device. For example, LED devices have to use a singly linked list to link the LED devices in the system. Easy to find.
In the interface implementation, there is no hardware-related implementation code, just a simple call to the abstract method. The abstract method needs to be done by a specific HC595 device. Since the implementation of each interface is very simple, its implementation is often stored directly in the .h file as an inline function.
For ease of reference, the contents of the abstract HC59 device interface file (am_hc595.h) are shown as shown in Listing 8.20. The corresponding class diagram is shown in Figure 8.6.
Listing 8.20 am_hc595.h file contents
Figure 8.6 Abstract HC595 device class
In the program, am_static_inline is the identifier of the inline function, which is defined in the am_types.h file. The actual content of the definition is related to the compiler. If you use the GCC compiler, it is defined as follows:
Since the identifiers of inline functions are different in different compilers, in order for the user to use a uniform identifier, AMetel uniformly defines the inline identifier as am_static_inline, so that the user can use the identifier as inline in any compiler. Identification, no need to care about the details related to the compiler.
2. Specific HC595 equipment class
Take the SPI control HC595 output data as an example to describe the implementation of the specific HC595 device. First, a concrete device class should be derived based on the abstract device class. The class diagram is shown in Figure 8.7.
Figure 8.7 Specific HC595 device class
The specific HC595 device class can be defined directly:
Am_hc595_spi_dev_t is the specific HC595 device class. With this type, you can use this type to define a specific HC595 device instance:
When using the SPI to control the HC595, you need to know the HC595 related information, such as the latch pin, output enable pin, SPI clock frequency and other information.
In particular, when the SPI outputs data, the bit order at the time of data output can be specified: the highest bit first output or the lowest bit first output. The first output bit determines the level of Q7 at the HC595 output, and the last output bit determines the level of Q0 at the HC595 output. Obviously, the output order of the bits directly affects the output of the HC595, so the specific output order should be determined by the user.
Based on this, the device-related information that needs to be provided by the user is stored in a new device information structure type:
If you use the MiniPort-595 and it is used in conjunction with the AM824-Core, its corresponding device instance information can be defined as follows:
For the same reason, it is necessary to maintain a pointer to device information in the device class. In addition, since the HC595 is equivalent to an SPI slave device when using the SPI to control the HC595, in order to communicate with it using the SPI interface, a corresponding SPI slave device needs to be defined for the HC595. Two new members are added. The complete HC595 device definition is for:
Obviously, before using the SPI to control the HC595, you need to complete the assignment of each member of the device. These tasks are usually done in the driver's initialization function. The prototype that defines the initialization function is:
among them:
P_dev is a pointer to an instance of type am_hc595_spi_dev_t;
P_info is a pointer to the instance information of the am_hc595_spi_info_t type;
Handle is an SPI handle, which is convenient for using SPI to output data. The return value of the initialization function is the HC595 handle. Based on the device instance and instance information defined above, the call form is as follows:
The return value is the handle of the HC595 instance and can be used as the argument to the first parameter (handle) of the HC595 general interface. An example of the implementation of the initialization function is shown in Listing 8.21.
Listing 8.21 Initialization Function Implementation Example (SPI Control HC595)
In the program, a standard SPI slave device is first established to facilitate subsequent data transmission using the SPI interface, then the p_info member is initialized, and then the assignment of p_funcs and p_cookie in the abstract HC595 device is completed. Finally, the device address is returned as the handle of the user operating the HC595. . Among them, pfuncs is assigned the value of &__g_hc595_spi_drv_funcs, which contains the concrete implementation of the three abstract methods. For the complete definition, see Listing 8.22.
Listing 8.22 Implementation of the abstract method (SPI Control HC595)
It can be seen that using the GPIO interface am_gpio_set() to control the output level of the OE pin implements the HC595 enable and disable functions, and uses the SPI interface function am_spi_write_then_write() to implement the transmit data function.
For ease of reference, the contents of the specific HC595 device interface file (am_hc595_spi.h) are shown in Listing 8.23.
Listing 8.23 ​​am_hc595_spi.h file contents
Connects PC or laptop with the projector, LCD monitor, and other video display system through VGA connections
Fully shielded VGA / SVGA extension or replacement cable
Supports resolutions at 800x600 (SVGA), 1024x768 (XGA), 1600x1200 (UXGA), 1080p (Full HD), 1920x1200 (WUXGA), and up for high resolution LCD and LED monitors
Gold-plated connectors; 100% bare copper conductors
Each SVGA Cable have two high density HD15 connectors with thumbscrews
Camera Cable,Camera Usb Cable,Usb Camera Adapter,Camera Link Cable
UCOAX , https://www.ucoax.com