Chapter Four: Programming the C167 1. C167 Programming Tools The Keil IDE (Integrated Development Environment) is used to program the C167 in the C programming language. It writes to the board RAM an executable version of your code. This tool is used to design and test your program. Once you are satisfied it is working correctly, you can “permanently burn” the code onto FLASH using Phytec FLASH tools. But, FLASH is reprogrammable so you can erase FLASH memory using the software and download new code; the number of times this can be done is around 100,000. 2. Embedded Systems Programming Concepts You MUST remember, you are writing code for a board that has no monitor, no keyboard or hard disk. So, it may feel weird at first. Nevertheless, such code is usually very clean and simple as you will see. This kind of programming is called embedded systems programming. You are writing code that is going to run on an independent system, the CalBOT. The system need not be a robot, for instance your microcontroller may control the flight control systems of a Boeing 747. Hence, unlike writing code on a computer, you have to make SURE your program is not buggy. For instance, if your flight controller program crashes, the outcome could be disastrous! 3. Downloading the Skeleton Project File Lets start writing programs! We have already configured Keil for you and made a skeleton project file that you can use when writing programs for the C167. There is a link in the Robotics Notes web page (http://wwwinst.eecs.berkeley.edu/~ee40/calbot/webpage/index.htm) to the CalBOT project skeleton. But, first: Create a new directory in your network home directory 1 . Name it ‘CalBOT_project_skeleton’. 2. Download all the files under the CalBOT_project_skeleton link in the Robotics Notes web page. Make SURE you save the files as of type ‘All files’. 3. Again, if you have any questions, email me ([email protected]), ask your TAs, ask your peers etc etc. 1. 1 This is NOT the desktop. You need to save it under your login in the network d rive (usually the U drive). 12 4. Understanding the Keil IDE First, start up Keil. Double click on the icon on your desktop. Then: 1. Click on Project and then Open Project. Navigate to the CalBOT_project_skeleton directory and choose the CalBOT project. You should see the screen in figure 1. Figure 1. The Keil IDE startup screen The two important windows are shown in figure 1. The PROJECT WINDOW displays the list of files in the project. The CODE WINDOW shows the code you are currently working on. Double-click on main.c to open the file in the code window. The code for main.c is shown below. /* Header files */ #include <reg167.h> (1) /* Global variables and defines */ /* Initialization functions */ 13 void InitLEDs(void) { DP2 = 0xFFFF; /* Turns on all LEDs */ P2 = 0x0000; } (2) (3) void Initialize(void) { InitLEDs(); IEN = 1; /* Enable Interrupts */ (4) } /* Utility functions */ void kludgyWait(void) { float i; (5) (6) /* Approx. 1/2 sec delay */ for(i = 0;i < 2500;i+=0.1) { ; } (7) (8) } void main(void) { Initialize(); (9) for(;;) ; (10) } Program 1. Turning LEDs on The numbers in parentheses on the right of the code are line numbers inserted by me for reference. Look at lines (2) and (3). These two lines are fundamental to programming the C1672 and it involves a central microcontroller concept called ports. Figure 2 shows how ports help a microcontroller talk to the outside world. Figure 2. Mic rocontroller ports 2 Refer to appendix A if you do not understand hexadecimal and binary numbers 14 5. Ports and C Programming You can think of a port as a gateway for data flow (hence the name, “port”). Data can either come into the microcontroller from a port, or flow out of a microcontroller through a port to the outside world. For instance in figure 2 above, port 5 is configured as an input port and port 2 is configured as an output port. Data comes into the microcontroller as a time varying voltage, V(t). Analog to digital converters (A/D converters) in the C167 convert this analog voltage into digital data. The C167 then operates on this digital data and the result is sent to an OR gate through port 2. What does PORT5_1 mean? Data in the digital world simply consists of two numbers: 0 and 13 . The 0 usually refers to a switch (say a transistor) being off (that is, connected to the lowest voltage in a circuit, usually ground) and the 1 refers to a switch being turned on (say a transistor that is connected to the highest voltage in a circuit). So, PORT5_1 refers to bit 1 on port 5 in the C167. The maximum number of bits within a port in the C167 is 16 (hence the C167 is a 16-bit microcontroller). Notice that this is the maximum number, some ports in the C167 have only 8 bits (Port 8 and Port 7). Some ports are special and can handle only specific types of data, for instance Port 5 can handle only analog data. Chapter 7 has a list of which ports on the C167 are available to the user. How do you say if the port receives data or sends data? By setting a direction port. For instance, in program 1, DP2 is the direction port for port 2. Setting a bit to 1 in DP2 tells the C167 that the corresponding bit in port 2 is used to be used as an output port, that is send data only. Hence, referring program 1, line (2): DP2 = 0xFFFF tells the C167 that all the 16-bits in port 2 are to be used as output and line (3) P2 = 0x0000 tells the C167 that all the 16-bits in port 2 have a value of 0. Before we move on, look closely at figure 2. component in figure 2? How could you avoid using it? 3 Can you spot the redundant Yes, your computer works because a bunch of 0s and 1s happen to be at the right place at the right time. 15 The OR gate in figure 2 is redundant. Instead, you could just write an if statement in your C program to test if Port2_1 OR Port2_2 is logic 1. (more on the if statement in chapter 5). This is the main reason for using digital control – avoiding hardware redundancy. Suppose you wanted to check for the condition: Port2_1 AND Port2_2. If you had used the external OR gate, then you probably would have to unsolder the OR gate and put an AND gate in its place. With software its easy, you just change the clause in the if statement to an AND. The rest of program 1 illustrates some other concepts of C programming. First almost every line in C should end with a semicolon, the exceptions are loops, function implementations and preprocessor directives. Do not worry about these terms, they will become clear as you read this manual. Second, blocks of C code are enclosed in curly braces { }. You don’t have to worry about which blocks of C code to enclose in curly braces, it will become clear as you read the manual. Line 1: #include <reg167.h> means include information about ports etc in your program. This helps you refer to port 2 as P2 and also has information about control and data registers. Control and data registers are the subject of chapter 5. This line is known as a PREPROCESSOR DIRECTIVE. You don’t have to remember this term, just don’t put a semicolon at the end of this line! Line 4: IEN = 1 means enable interrupts. The topic of interrupts is beyond the scope of this manual. You don’t need to understand this line to build the CalBOT, as a matter of fact you can build pretty advanced robots without interrupts. Nevertheless, for the curious an excellent reference is Patterson and Hennessy's Computer Organization and Design. Line 5: void kludgyWait(void) is the start of a FUNCTION. Functions are used to split up your program into manageable pieces. The format of a function in C is: Return-type functionName(arguments) { function statements ………………… } The functionName should be obvious; it can consist of upto 32 characters and must not begin with a number. A function takes some arguments, does something (hopefully useful) with them and returns a value. In our case, our kludgyWait function doesn’t take any arguments and doesn’t return any, hence the type void. We will cover functions in more detail in chapter 5. By the way, I named my function kludgyWait because it doesn’t wait exactly for 0.5 seconds. What do you mean by “waiting”? 16 It means if you run this function, it takes approximately 0.5 seconds for this function to finish executing. How does the function accomplish this? By using lines (6) and (8). Line 6: float i is the DECLARATION of a VARIABLE. A variable (as the name implies) is used to hold different data at different times in your program. The declaration tells C what kind of data it can hold, here a float means the variable i can have a decimal number. Line 7: /* Approximately ½ sec delay */ is a comment. Anything between a /* and */ is ignored by C, feel free to use them to make your program more understandable. Line 8: for(i = 0;i < 2500;i+=0.1) is a LOOP in C. A loop (as the name implies) tells C to repeat the statements in the loop BODY (the lines following the loop and enclosed by { } ) to be repeated. In this case, there are no statements in the body. This is indicated by the single semicolon. How do you tell C how many times to repeat the statements in the body? This is accomplished by the loop statement. You read the statement as: 1. Start with i = 0 2. keep executing the body of the loop as long as i < 2500. 3. Once you execute the body once, increment i by 0.1. Number 1 is called the initialization step, number 2 is called the conditional and number 3 is called the increment. So, back to our original question: how does the kludgyWait function wait? Well, it takes time to increment i by 0.1 until we reach 2500, this time is approximately 0.5 seconds. Hmmm, it takes 0.5 seconds for a 20 MHz controller to count to 2500, 1/10 step at a time? Well, i is a float variable. Floating point calculations are EXTREMELEY slow. Line 9: void main(void) is the start of the main function. The main function is special; C begins executing your code immediately after this statement. In our case, the main function simply calls another function Initialize(). After this is the last statement in your embedded program. Line 10: for(;;) is an INFINITE loop. It tells C to keep on executing your loop statements forever. Now why on earth would you want to do that? Remember, you are writing an embedded program. Your code is going to execute on a microcontroller that may then be used in a Boeing 747 flight control computer. So, you want to be absolutely sure that your program doesn’t stop executing. 17 6. The KitCON-167 Great. What the heck does this program do? As I mentioned in chapter 2, the KitCON-167 is a like a “motherboard” your C167. It contains a plethora of components like RAM, serial ports and power circuitry that make your microcontroller tick. Among these components are 18 LEDs (light emitting diodes) out of which you can use 16 4 . Figure 2 in chapter 2 shows the location of these LEDs, which I refer to as “status LEDs”. As the na me implies, an LED emits light when turned on. What makes the 16 status LEDs so special? They are connected to port 2 of the C167 through the KitCON connector! Aha, this program simply turns on the LEDs connected to port 2. So, why do we write a 0 to the Port 2 to turn the LEDs on in program 1? Well, the designers of the KitCON-167 decided to make these LEDs turn on when you write a 0 to Port 2, NOT a 1. Why, I don’t know! So, in program 1 we write a 0 to Port 2 to turn on all the LEDs. 8. Downloading a Program to the KitCON-167 What do you do to put this program on the KitCON-167? First, you have to compile the program: send it through Keil’s C compiler that translates your program into object code that is then translated by a linker into executable code. It is very easy to do this, just click on Project as shown in figure 3. Then click on Rebuild all Target files. You should not receive any warnings or error messages. If you do, contact your TA, ask your peers or email me ([email protected]). In order to actually download the program, make sure your serial cable is connected to the RS-232 (serial interface) port of the KitCON, refer to figure 2 in chapter 2. Once you have done this, turn on the KitCON-167. Insert the adaptor to the connector and make sure the dummy plug is removed, as shown in figure 4. Once you remove the dummy plug, the power LED should light up as shown in figure 5. Now, click on Debug followed by Start/Stop Debug Session. You should see a blue progress bar at the bottom left corner of your screen. Once the program has finished downloading to the KitCON RAM, you will see figure 6. Click on Debug again and click Go. The LEDs should light up as shown in figure 7. 4 The other two are used to indicate if your board is on and if it is connected to your computer. 18 Figure 3. Compiling and linking your program Figure 4. Power supply connections 19 Figure 5. The red power LED turns on indicating the board is receiving power Figure 6. Keil ready to run your program 20 Figure 7. LEDs all lighting up! 21 8. Summary This chapter covered a lot of ground. In order to fully understand these concepts, I suggest the following: 1. Learn how to turn on and off each LED in port 2. 2. Use the kludgyWait function to write a program that blinks the port 2 LEDs. In the next chapter, we will add more tools to your microcontroller know-how, namely using control and data registers, using PWM to control the speed of the motor and the concept of a motor driver. After completing chapter 5, you should be able to control the speed and direction of your motor. 22
© Copyright 2026 Paperzz