Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90128
  • 博文数量: 34
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 275
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-13 23:05
文章分类

全部博文(34)

文章存档

2011年(1)

2010年(7)

2009年(26)

我的朋友

分类:

2009-06-29 21:42:37

Lab Manual Section 3: Serial Port

2-0: Introduction to the Serial Port

This lab is due on Sunday, December 2, by 23:59:59.

Objectives

  • Have the ability to write programs that perform serial communication
  • Have the ability to properly configure UART settings

Further Reading

  • Microcomputer Engineering, pg. 385-89
  • MC68HC11 Reference Manual, pg. 357-60

Assignment

The program below should keep printing the character A to the serial port forever. There is, however, one piece missing: the baud rate still needs to be set. Look through your book and figure out what settings are needed to set the baud rate to 9600 bps. An important bit of information: the robots' MCUs have a crystal frequency of 8 MHz; this allows the clock speed to operate at 2 MHz. In particular, you should refer to Tables 9-1 and 9-2 in the HC11 Reference Manual.

When you think you have it right, run minicom to communicate with the serial port on the computer. No configuration should be necessary, but if it is, configure it to use the following settings:

Bits per second: 9600
Data bits: 8
Parity: none
Stop bits: 1
Flow control: off

Once minicom is running and you have the robot connected and you have uploaded your program, you can start the program on the robot. If everything goes as planned, the screen should fill with As.

minicom uses Emacs-like commands. To quit, type C-a q, then press Enter to confirm. Type C-a z for some very basic usage information.

void pc (char c) {
	volatile char *scsr = (char*) 0x102e;
	volatile char *scdr = (char*) 0x102f;

	/* Wait until the serial port is available for sending data */
	while (!(*scsr & 0x80));

	/* Send the data */
	*scdr = c;
}

int main (void) {
	/* notice the volatile keyword on these variables.  This tells the C compiler that other things besides your program may be changing its value
	so not to perform optimizations that assume it stays the same. */
	
	/* pointer to the baud control register  locate at memory address 0x102B*/
	unsigned volatile char * baud = (unsigned volatile char *)0x102B;
	/* pointer to serial communication control register 1 */
	unsigned volatile char * sccr1 = (unsigned volatile char *)0x102C;
	/* pointer to serial communication control register 2  */
	unsigned volatile char * sccr2 = (unsigned volatile char *)0x102D;
	/* pointer to serial communication status register */
	unsigned volatile char * scsr = (unsigned volatile char *)0x102E;
	/* pointer to serial communication data register */
	unsigned volatile char * scdr = (unsigned volatile char *)0x102F; 
	
	// Initialize serial
	*baud = // ? figure out this setting
	*sccr1 = 0;  // 1 start bit, 8 data bits, 1 stop bit
	*sccr2 = 0x0C; // enable transmit and recieve
	// end initialization

	while(1) {
		pc('A');
	}

	return 0;
}

Now take a look at the printString () function you wrote many labs ago (remember that?). Notice how you used to use the print_char () function to print each character. You'll need to modify the routine to print over the serial line instead.

Note that the initialization of the serial port only needs to be performed once. Therefore, you should make a new function, serial_init (), to initialize the serial port. You need to call this function before using the serial port for communication.

Once you have done this, try using your new printString () function to print something over the serial port to the terminal.

Remember, you can use your old routines, like printHex (), printBinary (), printUnsignedDec (), and printSignedDec () to print debugging information from the robot. You'll find that debugging becomes much easier while using the serial port.

Grading Criteria

The TA will:

  • Verify that the program works as expected
  • Verify syntactic correctness in the student's code
  • Observe a demonstration of the running program presented by the student
 

Input & Polling

Objectives

  • Be able to use C macros to write more clean and concise code
  • Monitor input using polling
  • Be able to use Analog to Digital converters to read input when guided by an example program

Further Reading

  • The C Programming Language pg 88-89
  • Microcomputer Engineering pg 401 - 406
  • M68HC11 Reference Manual pg 472 - 478

Macros

looking back on the previous lab you will remember how we had to use long variable declarations such as

unsigned volatile char * sccr1 = (unsigned volatile char *)0x102C;

and then access them as follows

*sccr1 = 0;

These are very tedious to work with so in this lab we will use the macro feature of C to make things easier. Macros basically allow you to define phrases that C will replace with code before your file is compiled. you can define them using the #define driective. The macro below defines SCCR1 to be the contents of a character stored at the memory address 0x102C.

#define SCCR1 *((unsigned volatile char *)0x102C)

Everywhere you type SCCR1, the compiler will replace it with *((unsigned volatile char *)0x102C). To read from or write to SCCR1 you just use it like you would a normal character. so to set it to 10 you would use SCCR1 = 10;. If you take a look at the file portsio.h then you will see that we have defined most of the ports and bits for all the registers that will be used in these labs all you have to do is include that file in all the files where you use the macros. As you can see in the example below it makes the code much cleaner and easier to read. Most of the register macros are named exactly the same as the registers are in your book. Also note that macros in C are traditionally all capital letters so that you can tell them apart from other parts of the code

Assignment

Below is a program that reads the input from the buttons using the analog to digital converter. once the conversion is done the result is stored in the BUTTONS register. use your printUnsignedDecimal function to print out the conversion values for when the buttons are pressed. Once you have the robot printing values out over the serial line then record the values for all possible combinations of button presses

#include "portsio.h"

int main () {
	/* Enable analog to digital converter by setting the ADPU bit in the OPTION register */
	OPTION |= ADPU;
	
	char result;
	
	while(1) {
		ADCTL = 0;  // writing to the analog to digital contol register signals the AD converter to start its conversion.
		
		// once the conversion is finished then the CCF bit in the analog to digital control register will be set.
		while(!(ADCTL & CCF));  // wait until conversion is finished
		
		result = BUTTONS; // BUTTONS is the register where the output of the conversion is stored
		
		// print out the results
	}

	return 0;
}

Grading Criteria

Program should print number read from button a/d and also name the combination. Good solutions are not brittle. README should indicate how their button identification algorithm was desginged and how they picked any threshold values.

  • Verify that the program works as expected.
  • Verify syntactic correctness in the student's code.
  • Observe a demonstration of the running program presented by the student

Interrupts

Objectives

  • Be able to set up and use basic interrupts.
  • Use timers on a microcontroller to manage real-time events

Further Reading

  • Microcomputer Engineering pg 330 - 355
  • M68HC11 Reference Manual pg 367 - 381

more comments, FLIP all LED bits

Assignment

  .sect text

  .globl	main
		
		ldd 0x100E   ; load current timer count TCNT
		addd 40000	 ; 20ms = 40000 cycles
		std 0x1018	 ; store new time into output compare register OC2
		
		ldd ledHandler
		std 0xFFE6	; set OC2 Interrupt Vector
		
		ldaa 0x40	; enable OC2 interrupts
		staa 0x1022	

		
		; enable interrupts
		cli
		
		
   .globl ledHandler
		
		; toggle led
		ldaa 0x1000
		eora 0x20
		staa 0x1000
		
		ldd 0x1018  ; load current output compare count 0C2
		addd 40000	 ; 20ms = 40000 cycles
		std 0x1018	 ; store new time into output compare register OC2
		
		ldaa 0x40
		staa 0x1023
		
		; this is an interrupt subroutine so we use rti instead of rts
		rti

Modify the program above so that the LED is toggled once every second.

The timer is a 16-bit number which is too small to count the 2 million cycles needed for 1 second. You will need to count how many times the interrupt handler routine is called and only toggle the led at the appropriate count

Make new lab with enumerated speed: fwd_slow, rev_slow, fwd_nor, rev_nor, rot_right, rot_left

Grading Criteria

  • Verify that the program works as expected.
  • Verify syntactic correctness in the student's code.
  • Observe a demonstration of the running program presented by the student.

Motor Control

Objectives

  • Be able to write a C program to control an arbitrarly number of actions using one interrupt handler
  • Be able to use pulse width modulation to control peripherals

Further Reading

  • Microcomputer Engineering pg 330 - 355
  • M68HC11 Reference Manual pg 367 - 381

Assignment

In the example only one of the motors is running. Modify the example so that both motors are running in the same direction with the same speed. Remember that the motors are hooked up in opposite directions so you will have to send different signals to each motor to have them go the same direction. You can do this using only one interrupt handler, counting cycles and having a time variable for each motor.

#include "ioports.h"

static inline void
cli(void)                       /* clear interrupts */
{
  /* the __asm__ instructions is not C code but is a compiler directive for Gcc (the compiler that you are using) that
   * allows you to insert assembly code directly into your C code. */
  __asm__ __volatile__ ("cli");
}

/* note interrupt attribute!! this tells the compiler to use an rti insted of rts when returning from the function*/
void interruptHandler (void) __attribute__((interrupt));    

long elapsedCycles;
short leftOnCycles = 5000;
short leftOffCycles = 35000;
long leftExpired;

long nextInterrupt;

void interruptHandler() {
	elapsedCycles += nextInterrupt;
	nextInterrupt = 64000; /* 64000 is the max time we will be using between interrupts*/
	
	/* check if it is time to switch pulse state*/
	if(leftExpired <= elapsedCycles) {
		PORTA ^= LMOT;
		
		if(PORTA & LMOT) {
			leftExpired = elapsedCycles + leftOnCycles;
		} else {
			leftExpired = elapsedCycles + leftOffCycles;
		}
	}
	
	/* if this is the soonest and is less than the max time timer value
	 *  then use it as the next interrupt time */
	long timeLeft = leftExpired - elapsedCycles;

	if(timeLeft < nextInterrupt) {
		nextInterrupt = timeLeft; 
	}	
	
	/* set the time of the next interrupt*/
	TOC2 = TOC2 + nextInterrupt;
	
	/* clear the output compare 2 interrupt flag to allow more interrupts to occur*/
	TFLG1 |= OC2F;
}


int main (void) {
	elapsedCycles = 0;
	leftExpired = 0;
	nextInterrupt = 2000; /* the first interrupt will occur after 1mx */
	
	/* Set bi-directional port to output  (For right motor) */
	PACTL |= DDRA7;  
	
	/* set the interrupt vector to the address of our interrupt handler function */
	OC2_VECTOR = (unsigned short)interruptHandler;
	
	/* set the first interrupt to occur in 1ms*/
	TOC2 = TCNT + nextInterrupt;
	
	/* set output compare 2 to generate interrupts */
	TMSK1 |= OC2I;
	
	cli(); /* clear the global interrupt flag to allow interrupts to occur*/

	return 0;
}
  

  

Grading Criteria

  • Verify that the program works as expected.
  • Verify syntactic correctness in the student's code.
  • Observe a demonstration of the running program presented by the student.

Interrupt driven input

Objectives

  • Use interrupts to periodically monitor input
  • Be able to configure and use Analog to Digital converters to read input

Further Reading

  • Microcomputer Engineering pg 401 - 406 & pg 330 - 355
  • M68HC11 Reference Manual pg 472 - 478 & pg 367 - 381

Assignment

Use your knowledge of how the buttons work on the robots and your knowledge of interrupts to write an interrupt handler that checks the buttons every second and prints out over the serial line the name or names of which button or buttons were pressed.

Grading Criteria

  • Verify that the program works as expected.
  • Verify syntactic correctness in the student's code.
  • Observe a demonstration of the running program presented by the student.

 

阅读(670) | 评论(0) | 转发(0) |
0

上一篇:Lab Manual Section 2: LED Labs

下一篇:Append

给主人留下些什么吧!~~