We’re at the final lesson in this module where we will see the results of our effort working on the development board. 我们进入该模块的最后一课，在这里我们将会看见所有投入在开发板上努力的成果
The very classic first step in any programming language is to get “hello world” printed on screen. 各种编程语言开篇的经典第一步都是在屏幕上显示“hello world”。
This ensures your development environment is responding, your compiler is working, and your program is outputting properly to the target. 这表明了你的开发环境正常，你的编译器工作正常，以及你的代码输出也正常。
In the embedded world it’s no different, 在嵌入式的世界里，没什么不同
but instead of outputting a string – which actually involves quite a lot of code not to mention many embedded systems don’t have any sort of display-embedded developers blink an LED. 在嵌入式的世界里，没什么不同，只是不同于输出字符串 – 实际上大多数嵌入式系统代码工作起来并无结果显示 – 嵌入式开发者让LED闪烁
Even after 20 years of working with microcontrollers, 即使从事了20年以上的微处理器工作，
I still feel a great deal of satisfaction (and relief) when the new piece of hardware I’m working with comes to life with that steady heart-beat like output. 我仍总是能感受到成功设计出一个新硬件并使之如心跳般稳定工作带来的巨大满足感
Though to many people it is “just a blinking light” to an engineer who has spent hours, sometimes days learning, debugging, testing, and trying again and again, 尽管对于很多人来说“只是个闪光信号灯”，但是对于工程师来说，意味着投入的无数个小时，学习，调试，测试，经历无数次的失败，
that blinking light may represent the very essence of their soul! 闪光信号灯代表了他们的精神！
Ok, that might be going a bit far, but it really is exciting and an extremely important step to being successful with microcontrollers. 回归正题，在微处理器方面的成功意义十分重大并令人兴奋。
So far in our project we have loaded three registers to get our development board ready to read input from a button and take control of an LED. 目前为止我们使用过三个寄存器来使得开发板可以读取按键输入指令来控制一个LED。
We also have a loop that does nothing except kill some instruction cycles.
Reading an input and writing an output are operations facilitated by other registers in the PIO peripheral.
If you look back at the table of registers on page 522- the user guide, you can find the four registers that we’ll need to do our IO: SODR, CODR, ODSR, and PDSR.
Let’s look at each one more closely.
SODR stand for Set Output Data Register.
When you write a 1 to the bit locations in this register, you tell the processor that you want the corresponding pin to be at logic high (or VCC).
This will happen as long as you have granted yourself access to writing this register (which we have), you’ve enabled output (which we did) and the hardware attached is able to rise to that level (that is kind of another lesson – but take our word for it that our development board is set up properly.
The CODR register is the opposite. It clears output data register.
When you write a 1 to the bit locations in this register, you tell the processor you want the corresponding pin to be logic low Again, as long as the aforementioned conditions are all true, that pin will respond.
The ODSR register is the output data status.
This is the status register that will change as the result of SODR or CODR writes.
This is a little bit tricky because this register tells you what the microcontroller is trying to set the corresponding outputs to.
If any of the conditions we mentioned are not true, then the actual state of the pin may not reflect the contents of this register.
Therefore, this is NOT the register you should look at for reading an input or deciding what the current status of the pins are.
To do that, we use the PDSR ( or Pin data status register). This is used to actually read the state of the pin.
The logic value here reflects the current digital state of any pin regardless of whether or not it is configured as an input or output.
The first thing we’re going to do is make an LED blink.
After that, we will control the blinking using the button.
Remember that the BUTTON is located at bit 0 (0x00000001) and the LED is at bit 19 (0x00080000).
What does a blinking algorithm look like?
You will learn very quickly that visualizing, planning and designing your code is very important.
This is heavily emphasized throughout the entire EiE program.
While you could likely start writing your blinking code right away, because it’s pretty simple, you will definitely not be able to just start writing code when we ask you to monitor wireless input signals, read data messages, and display real-time data on the LCD.
So we start practicing now and build some good habits that you can use later!
We can draw a simple flow chart to show what needs to happen to blink the LED.
The algorithm is indeed simple. But we want to visualize it to make sure we know what’s going on.
So first the processor boots up and does all the required configuration – we simply show this as “BOOT” on the flowchart.
Next, we need to make a decision: If the LED is ON, we need to turn it OFF. If the LED is OFF, we turn it ON.
After that, we wait some time and then repeat that whole process, starting with the LED check.
We do this forever- that’s how embedded system almost always works. It never ends .
Let’s go over to IAR and translate all this into code.
We have already booted up and initialized our GPIO registers. So the first thing we want to do is check the state of the LED.
There are a few ways to do this. We could look at the ODSR register since it holds what should be output on the pin.
So instead, we’re going to create a Boolean variable to track the current state of the LED.
We’re going to call this bLedOn. We’re going to initialize it to the FALSE state.
Following our flow chart, we want to check this variable. If the LED is on, we’re going to turn it off. If the LED is off, we’re going to turn it on.
??????
Now, how do we do that?
The register that we need to access, starts out in the same way but it’s called the PMC- Power Management Controller.
And this particular register is called PMC-PCER.
We’re going to use a special notation that you’ll see very often in ARM and probably any processor code where we take a bit, kay so where this is like 0x1 or bit-0 being set.
And were going to shift it by a certain number.
And there’s a constant that’s set up for the number of the PIOB peripheral.
So this takes the number 1, and it shifts it over into the right bit location that’s set up in this PCER register to enable the clock.
Again, details we’re not going to go into- you’re going to have to kind of take our word for it.
You can definitely read the data sheet on this register to understand it more but we’ll leave that to you as an exercise.
The second register we need to adjust disables a special timer peripheral called a “watchdog timer”.
So very briefly again, the watchdog timer is something that will reset the processor if it ever counts down to zero.
So, almost every processor has one. And the main purpose is to reset the system if it ever gets stuck.
It’s kind of something that should never happen but if it does, at the very least, you can start up your system again.
We cover this in EiE FW1 so for now we’re going to simply write the register that disables this feature.
So our comment is * Disable the watchdog * and in this case, our register name, our register section is called WDTC- Watchdog Timer Control and the register we want is called WDMR.
The bit name is called- again in a predefined location- and you can get this from the data sheet.
So it’s watchdog timer control. WDDIS which is Watchdog Disable- which kind of makes sense.
Would you ever know this if you haven’t read the data sheet or didn’t have experience with this particular processor? Mmm, probably not. Although as you work with microcontroller, you’ll probably be thing; hey, is the watchdog timer disabled? Is it going to run? And any weird behavior that you see like sudden resets in your code- might be attributed to the watchdog.
Now we would really like to show you this working on our real development board. So to do that, we have to make sure that all of our GPIO is configured correctly.
So what I’m going to do, I’m just going to paste in some code that I have copied and ready. And this sets up all of the PIOB-GPIO to makes sure that our real hardware is working.
And we’ll just put it in an “if-1, end-if” statement here, so we can comment it out quickly to keep running our simulator version.
So, with that in place, we can build this code once more. Make sure everything works and change over to our hardware.
So “options”, “debugger”-again, run our J-link.
One other thing we need to do, because we’re running a real processor, we need to slow down this loop.
1000 iterations through this loop is not enough, we won’t even be able to see the blinking.
We actually need to increase this to 100000. And that’s going to give us a blink rate of about 5x per second.
And that’s just the way the hardware is set up, and the speed that it defaults to.
Download updates our code build, loads our real hardware and when we run this code in full speed, we can disable our breakpoint and you can see we have a beautiful LED blinking.
Hello world!
The last thing we will do is use the button to decide whether or not the blinking LED will be shown.
If the button is pressed, we will execute the LED blinking code. If the button is not pressed, then we will skip the code.
Remember the button is active-low. So, when it’s not pressed, the input signal is high.
The state of the button will be at bit 0 in PDSR register.
To test a single bit, we can use an ‘if’ statement to check the result of a bit-wise AND operation like this:
/* Check bit 0 in PDSR */
So our “If statement”: If(AT91C_BASE_PIOB->PIO_PDSR & 0x00000001) We look at just that bit.
So you can write out on paper how this actually works. It does a bit by bit comparison, using a logical AND operation.
Now, because the button is active low, this will sort of behave opposite to what we want. If we want to run the code if the button is pressed, we need to negate this.
We could just do this and it will probably work. I think that would correctly negate the value in this register.
But, as good embedded programmers, we never leave anything up to chance. We could verify it on this compiler but it might be different.
So we can specifically make sure that this whole expression gets evaluated and then negated. And that’s just good programming practice.
So again we’re going to put in our structure.
So we’re going to round this entire section of code inside braces so it’s conditional on that check.
We can highlight all of this and press tab to fix our indenting.
We can put a comment here: so, button is pressed, so run the blink code. In the other section, we can comment: button is not pressed, so do nothing.
Put our “else”- but we want to make sure that the LED is off.
So we can copy our code from here that makes sure the LED is off. And because we don’t know exactly what state our Boolean variable in is at that time, then we’re going to make sure we initialize that back to FALSE.
Our project is still set to be running in the development board, so let’s build this. Make sure it builds correctly, put it onto our dev board and I want to set a breakpoint right here.
We’ll run to this code. Now let’s look at our registers here.
So let’s come down to the PDSR register and you can see we’ve got a bunch of values in here.
We know that our button is bit-0. So, this hex number here “F”, means that bits-0123 are 1111.
So if we step on our code, our button is not pressed, so we’re just going to make sure our LED is off, set our B-LED on to FALSE and then go through our loop.
While we’re going through this loop, I’m just continually clicking run.
I’m going to press the physical button on the development board and watch what happens. So I’m going to press the button, I’m going to step this so it updates the registers and you can see right here, that now the value in the PDSR register is E.
And in binary, E is 1110. So bit-0 has been changed to 0.
If I release the button and run the code again, you can see it goes back to F.
So if I keep doing that; I’ll press the button, you can see it goes to E- release the button- goes to F.
So all of these things are happening while the code is running.
So now let’s go back up to our breakpoint.
I’m going to press the button to make sure that the state changes before we do the statement. I’m going to press GO. So we’re going to quickly run through those 100000 cycles. I’ve got the button pressed down. You can see that our value is E which means this statement should now take us into our blinking state which is does.
Clear off this breakpoint, press to run at full speed and you can check out the hardware here, so our code is running, button is not pressed, no LED blinking.
If I hold down this button, then we start running our blinking code. Release the button and then we’re done.
And that concludes the “Getting Started” module for the EIE program.
I hope that you have enjoyed this lesson and are starting to see the exciting possibilities of embedded system design.
I’ve worked in this field for nearly 20 years, and I still find it exciting and interesting every day.
The use of microcontrollers in our lives continues to grow exponentially, so this is an area of electronics that will only get bigger and bigger.
Obviously having hardware is very important when it comes to learning about embedded systems.
The EiE development board has been carefully created to provide a ton of functionality including two processors.
The second processor provides wireless communications through Blue Tooth Low Energy (BLE) and ANT protocols.
It has everything you need for three full EiE programs.
The J-Link debugger is built in, and with the daughter board connector you can attach any other hardware.
We even have an Arduino shield adapter so you can use most Arduino hardware.
We’ve even started many real device for our customers using this development board.
Thank you for taking the time to learn with EiE, and I sincerely hope to see you for more lessons in the future!