博客首页 | 排行榜 |

设计我最赞的博客

个人档案
博文分类
视频邮票(Video Stamp)  2008-09-21 14:43
A Handy Display for Debugging Programs

Jose uses his "Video Stamp" system to debug his programs and display video from various applications. A PIC18F2520 microcontroller and three resistors form a rudimentary DAC to generate the NTSC-compatible video signal. Read on for the hardware and software specifics.

Back in 1971, my first project as a hardware design engineer was a"dumb" video terminal that displayed 64 characters per row and 32 rows. When finished, the logic and power supply filled a 12″ × 10″ × 8″ metal box. For those who do not remember,it was the time when the only available active components were discrete TTL and memory was implemented using recirculating MOS shift registers. Since then, and for sentimental reasons, every time a new generation of components has come out, I have mentally tried to redesign and shrink my first project using the new components.
In the mid-1970s, when microprocessors and bipolar memory became available, there was a turning point in video display design. Then,the now legendary Don Lancaster in his book, The Cheap Video Cookbook,pioneered the unorthodox use of microprocessors to design video displays.There were also other approaches,such as using a TTL counter to drive the address lines of a PROM. The PROM‘s data output then drove the sync signal generation and synchronized the data flow between the character memory, the character generator,and the shift register.

This project was an attempt to recreate that spirit. I produced a design that displays composite video with only a few components.

OBJECTIVE
My project receives serial data in an asynchronous format, 8 bits, 1 stop bit, and no parity bits at 9,600 bps(other rates are possible) and displays it on a conventional video monitor or a TV that has a composite video input(see Photo 1)。 The display has a capacity of 38 characters by 16 rows. An additional row is at the bottom of the screen. This is the Parameter row. It displays a blinking dot (I am alive),the last character received (both in ASCII and Hexadecimal), the receiving data rate, and a message area 20 characters long.


The received data is entered at the screen's current position in the bottom row. When the thirty-eighth character is received, all rows in the screen scroll up one position, the bottom row is cleared, and the following received character will be entered at position 1 of the bottom row.

All of this is accomplished using only a Microchip Technology PIC18F2520 microprocessor and three resistors that form a rudimentary DAC to generate the NTSC-compatible video signal. Connect one 0.1-μF capacitor between 5 V and Ground for decoupling purposes and all this can be mounted in a 2″ × 1″ prototyping board. It is a far cry from my first design (see Photo 2)。


MOTIVATION
As I was considering the Microchip PIC18F2520 for an unrelated project, I also looked at the possibility of using it as the only component to implement a video display. As the details fell into place, I realized that besides the challenge of cramming all of the functions into this one part, there was a practical reason. I figured I could use the final design every day as a debugging tool.

When developing a new application,it is very useful to know the state of several variables when the program runs through a particular part of the code. It is also useful to see how the variables change as we change an input. Of course, that can be done using breakpoints, but it is slow and cumbersome. If you are using C language,a printf statement or, as in my case, HSEROUT in PICBASIC PRO,the final product will display four or five variables to a line in the video display. Then, a trace of several lines will most likely pinpoint the cause of the problem.

To do this, I plug the Video Stamp into my prototyping board and then connect the TX side of the microprocessor being debugged to the RX input in the Video Stamp and connect the video output of the Video Stamp to a suitable video display. In my case,the video display is a small camper style TV that I bought at a local appliance store for $19. Refer to Photo 3 for a picture of the setup. I also use my PC video display that has a composite video input, but it is inconvenient to switch inputs and I prefer the small TV set. Once I have finished the project,I unplug the Video Stamp and put it in a safe place until next time.


The second situation is to add video display capabilities to a given project when there is a lot of data to be displayed. That was the case in a homebrew"environmental/alarm monitoring module" that displayed about 500 characters of information. For this application, I added the PIC and the three resistors to the PCB. For $5, I had a display capability. I then routed the video output to an unused composite video input in my home TV. By changing the input with the remote control,I was able to see all the data collected by the monitoring module.

THE VIDEO SIGNAL
The standard NTSC video signal can be interlaced or non-interlaced. I chose noninterlaced because it simplified the generation of the horizontal sync and does not change the quality of the display. Figure 1 shows the characteristics and timing of the horizontal raster line.


The horizontal line has a duration of 63.5 μs. This gives you a horizontal scanning rate of 15,748 Hz. To keep the vertical and horizontal sync locked together, generate the vertical sync based on a count of 262 horizontal lines. By changing the duration of line 262, you can obtain an almost perfect rate of 60 Hz for the vertical sync.

An important limitation is the video signal‘s maximum bandwidth. It should not exceed 3 or 3.5 MHz. Its value is equal to one-half of the frequency of the clock that shifts data out of the Video Shift register. We are very close to this limit, but given the built-in tolerance in TV design, it does not present a problem in actual practice. IMPLEMENTATION Conventionally, video generation logic contains several blocks (see Figure 2).Data memory contains the data to be displayed. It is addressed by the microprocessor to write the data to be displayed and by the timing module to read the data and feed the addresses to the character generator.


The character generator is usually ROM that contains the dot pattern for each character. It is addressed by the concatenation of the binary value of the character to be displayed and the timing module with the current raster line. I chose a 5 × 7 pattern because legibility is good and it enables me to display more characters than a 7 × 9 pattern.

The output of the character generator feeds the Video Shift register and is shifted out in serial form to the DAC. This video and the vertical sync added together form the NTSC composite video signal.

My implementation closely follows this model. Note that all of the different blocks, except for the DAC, are contained inside the PIC18F2520.

HARDWARE
Figure 3 reveals the extreme simplicity of the hardware: one PIC18F2520 microprocessor,three resistors, and one capacitor. That is it.


The PIC18F2520 was selected because it contains all the peripherals and features needed for this implementation. The clock is internally generated at 8 MHz and then multiplied with an internal PLL to reach 32 MHz. At this frequency, the instruction rate is 8 MHz and the instruction cycle is 0.125 μs. This is important because all the timings are generated using this frequency and it is very handy to have this kind of granularity. The generated frequency is accurate and very stable, provided that the 5 V is well regulated and noise free. It is important to add a 0.1-μF decoupling capacitor between pins 19 and 20.

The USART module provided serial data communication using the standard RS-232 protocol for asynchronous communications. It is programmed at initialization time to work at 9,600 bps,8 data bits, 1 stop bit, and no parity bits. Other configurations are possible,as noted in the software description. Only the receiver side of the USART is used.

The Timer0 module can operate as a timer or a counter in 8-bit or 16-bit mode and has an optional prescaler. I selected Timer mode, 8 bits, and no prescaler. The timer is at the heart of all the video generation timing. It is set up to invoke an interrupt every 63.5 μs.

The master synchronous serial port(MSSP) module is a parallel to the serial interface that can be programmed to execute two of the most common serial communication protocols in use today, I2C and SPI. I configured it to work in SPI Master mode to implement the Video Shift register. This is somehow an unorthodox implementation,but it works for my purposes.

The PIC18F2520 has 32 KB of program memory and 1,536 bytes of RAM. This is more than enough for this application and there is plenty of room to add more features. Only half of the RAM is used to hold the program variables and data memory. The program memory holds the program and the character generator. Again,there is plenty of room for expansion. For more details on the operation of these modules, refer to the PIC18F2520 datasheet.

Wiring a three-resistor voltage divider as a simple DAC has been extensively used in hobby projects. I have recomputed the resistor values to produce the theoretical voltages required by the NTSC signal for black,white, and sync levels. Then I chose the closest standard resistor value available.

SOFTWARE
The program was developed using the PICBASIC PRO (PBP) compiler tightly integrated into a Microchip Technology MPLAB IDE. This enabled me to use the editing and debugging facilities of MPLAB and to write part of the code using the MPLAB assembler. Mixing PBP and assembler in this particular application was absolutely essential because of the tight timing constraints in some parts of the code. With that said, it is not for the faint of heart because many subtle bugs may be introduced in your program-in particular, when you are using interrupts. Also, MPLAB enables the use of ICD-2, a low-cost debugger/programmer sold by Microchip, which helps immensely in the development cycle.

The program can be divided into three different sections: initialization,interrupt handler, and main loop. But before I describe the program, I will describe the data structures used:"RXdata" is a first in first out (FIFO)circular buffer that is 16 bytes long. It is used to temporarily store the characters received from the USART during the interrupt. The characters are retrieved by the background and stored in the ScreenBuff.

"ScreenBuffer" is a linear area of RAM that occupies Bank1, Bank2, and part of Bank3. This allocation is hardwired and assumes that the variables and other memory areas allocated by the compiler will never exceed Bank0. It contains the characters that will be displayed in the screen.

"ParamsBuffer" is an array 38 bytes long that contains the data to be displayed in the bottom line of the screen. "Chargen" is the character generator data that stores the dot pattern that defines each character. It is located in program memory at an address beyond the actual program and its location is also hardwired.

Extensive use of indirect addressing is made to access these locations. The PIC18F series has expanded the number of index registers and enabled the post-automatic increment of the index registers value. Without this feature, it would have been more difficult to implement some of the tight timing in the character‘s display routines. Data is not moved inside the ScreenBuffer as you scroll up. Only pointers held in the index registers are modified to display the correct data. I will now describe the different sections.

INITIALIZATION
When the program starts, set the internal oscillator to run at 8 MHz and enable the internal PLL to run at a final frequency of 32 MHz. Then, all ports are initialized, although only PORTA is used.

The USART is initialized by default at 9,600 bps, 8 bits, no parity bits, and 1 stop bit, but an option is given to set a lower speed by reading some straps located in PORTA. The available speeds are 1,200, 2,400, and 4,800. The SPI is then initialized to Master mode.

The ScreenBuffer is filled with a welcome screen, copied from a preset message located in program memory,and the parameter row is set to display the selected USART speed and other relevant data. In the data area,the pointers to the Rxdata are reset and the rest of the variables and pointers are initialized to the starting values.

Finally, Timer0 is enabled. The interrupts are set so only the interrupt from Timer0 overflow is allowed.

INTERRUPT HANDLER
This piece of code generates the horizontal and vertical sync signals and displays the video corresponding to the raster line. In addition, it reads the USART and places the characters received, if any, into the Rxdata FIFO buffer. It is written entirely in assembler to meet the tight timing requirements of sync signals and video generation. It is useful to have the characteristics of the NTSC video signal available when examining the code(see Figure 1)。


The routine starts by reloading the Timer0 with a value that will cause the next interrupt after 63.5 μs by overflowing the timer. It then saves the internal registers used by the interrupt.

Start the generation of the horizontal sync. It must last 4.7 μs while you check for end of frame. If that is reached, generate the vertical sync.

You must ignore a certain number of raster lines after the vertical sync to allow for the blanking interval and to vertically center the display inside the screen. Also processed here are the"special lines," such as the white line that separates the video display from the parameters row.

Once it is determined that a standard display raster line will be processed, initialize the pointer to access the first of the 38 contiguous characters in the screen buffer and wait to complete a further 4.7 μs before starting the display. Then, enter a part of the program that runs 38 times(once per character) the sequence of instructions exhibited in Listing 1,which is perhaps the most time-critical of the entire program.



For readers who are not familiar with the PIC18F family, I will briefly describe the instructions used here. The PIC has three 16-bit wide index registers, which can access the entire range of RAM available without paging constraints. A special operational mode enables you to read the data byte pointed to and then automatically increment the index register. This is the POSTINCx instruction, where x is the register used, which is FSR0 in this case.

Another special register, TBLPTRx,points to program memory. It is also 16 bits wide (both are wider) and formed by the concatenation of TBLPTRH and TBLPTRL. Executing a tblrd * instruction reads the location pointed to by TBLPTR and places its content in the register TABLAT. I use TBLPTR to access the character generator. TBLPTRH holds the current raster line of the current row and TBLPTRL holds the binary value of the character at this position. Therefore, TBLPTR points to the dot pattern that needs to be displayed next. I then read the dot pattern and move to the W register.

If you leave the SPI to work as designed, it will shift out eight dots per character, wasting some of the horizontal space. So, I disable the SPI when shifting out the sixth bit and reenable it immediately afterwards. This unorthodox method saves one dot per character, or 38 dots, and allows six more characters per row to be displayed. Finally, I move the next dot pattern that I have in register W to the SPI transmit register and start shifting it out.

Note that there is a NOP in the middle of the sequence. The move from TABLAT to SSPBUF is done with two instructions when it could have been done with one. All of this is part of the delicate equilibrium of the timing in this sequence. The same can be said of the fact that a loop is not used and the 38 copies of the same sequence are executed one after the other. Fortunately,there is plenty of unused program memory.

Just before exiting the interrupt routine, I check if a character has been received in the USART. If so, it is read and inserted in the FIFO buffer to be retrieved later by the background. This is simpler than having a separate vector for a USART interrupt and as reliable, because we sample every 64 μs and the maximum rate that a character can arrive is 1 ms. Finally, it exits after restoring all of the system registers used.

MAIN LOOP
The main loop is the actual program that runs in the background. Its function is to process the characters that arrive in the USART and place them in the screen buffer. First, a received character is displayed in the parameters row, both in ASCII and hexadecimal. If the received character is a control character (i.e., in the range of 00 to 20 hexadecimal), it is saved in the screen buffer and displayed as a white square. The only exceptions are the carrier return and line feed. Carrier return moves the cursor to position one of the current row. Line feed scrolls up the entire screen one row and clears the bottom row. The cursor remains at the same position.

Although I mentioned the cursor several times, there is no actual cursor displayed. It would be quite easy to add either as an underscore or a white box, blinking or static.

Another function of the main loop is to display a blinking dot in the first location of the parameters row. The implementation is very simple. A 16-bit counter is incremented at each iteration of the main loop and depending on the value of bit 15, a different character is displayed at that location. All it shows is that the background is up and running at the expected cadence.

DISPLAY AWAY
You now know that it‘s possible to design an inexpensive display for debugging and other simple applications. All you need are a few parts and the .hex file that's posted on the Circuit Cellar FTP site.

Given the simplicity of the hardware,no attempt was made to design a PCB. A small piece of prototyping board should be sufficient. You will also find the program listing on the FTP site, but bear in mind that you will need PICBASIC PRO to compile any changes. There is still plenty of memory and computing power left to implement a few more features (e.g.,escape sequences to clear the screen and position the cursor in any location).You can implement character attributes such as italics, reverse video, and blinking video or other fonts (e.g., Cyrillic or Greek).

I will leave that challenge to your inventiveness and ingenuity. I‘ll be glad to hear about any improvements.

Jose Sanchez started working in computers in his native Spain doing installation and maintenance on mainframes. After moving to the U.S. and graduating from Southern Methodist University with an M.Sc. in Computer Science, he worked for many years developing embedded applications as a contractor for a lengthy list of companies. After a long interlude in managerial tasks, Jose retired and returned to his original calling for fun and profit. You can email him at bubsemicon@gmail.com.

PROJECT FILES
To download code, go to ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2008/213.

RESOURCES
K. Jack, Video Demystified: A Handbook for the Digital Engineer,Newnes, Burlington, MA, 1955.

D. Lancaster, The Cheap Video Cookbook,Howard W. Sams, Indianapolis,IN, 1978.

Microchip Technology, Inc.,
"PIC18F2420/2520/4420/4520 Data Sheet," DS39631A, 2004.

SOURCES
MPLAB IDE and PIC18F2520 microcontroller
Microchip Technology, Inc.
www.microchip.com

PICBasic PRO Compiler
microEngineering Labs, Inc.
www.melabs.com
类别:嵌入式编程 |
上一篇:嵌入式Linux开发-II(Embedded Linux Development(Part 2)) | 下一篇:会计情报传送译码(AIS Transmission Decoding)
以下网友评论只代表其个人观点,不代表本网站的观点或立场