View previous topic :: View next topic |
Author |
Message |
marosh555
Joined: 23 Oct 2012 Posts: 9
|
Posted: Fri Oct 25, 2013 11:55 am Post subject: Split serial data |
|
|
Hi all, i have problem with reading data from serial port. Here is my code:
Code: | $regfile = "m644pdef.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 8
$framesize = 16
$baud = 9600
Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.4 , Rs = Porta.5
Config Lcd = 16x2
Cls
Cursor Off
Config Timer1 = Pwm , Pwm = 10 , Compare_a_pwm = Clear_up , Compare_b_pwm = Clear_up , Prescale = 1
Config Porta.6 = Input
Tlacitko Alias Pina.6
Dim Serial_data As Byte
Tlacitko = 1
Do
Inputbin Serial_data
Serial_data = Val(serial_data)
Lcd Serial_data
Waitms 1000
If Tlacitko = 0 Then
Printbin &H1
End If
Cls
Loop
End |
When I send on serial port number 1023 on LCD I see: 1 (wait 1sec+cls) 0 (wait 1sec+cls) 2 (wait 1sec+cls) 3(wait 1sec+cls). How I can split this number to a number 1023 or how I can send all number to my MCU? I can use this aplication for power control and I can send data from PC to OCRx register for PWM. Thanks
(BASCOM-AVR version : 2.0.7.6 ) |
|
Back to top |
|
|
Arera
Joined: 23 Sep 2007 Posts: 386 Location: Wuppertal, Germany
|
Posted: Fri Oct 25, 2013 4:27 pm Post subject: |
|
|
Your main loop contains a wait of one sec. You cannot do anything during that long time.
This is not a good stucture for any programm.
The main loop should run as fast and as often as any possible.
So what to do to refresh the lcd only one a second?
Here is what I do:
I set up a timer that triggrers an ISR every 100ms.
In the ISR I only (!) set a flag.
In the main loop I check this flag:
Is it reset? I do nothing.
Is it set? I reset the flag, i increase an counter-var.
Also in the main loop i check the value of the counter-var. Is it 10?
Then 10 x 100ms have past, meaning it is time to:
ReSet counter-var to 0, and write to the LCD.
Once you understood this structure, it is easy to create more counter-vars, thus creating more timers. They are all independent, and they all derive from one timer.
Did you notice, the main loop does not need to wait for anything, you are able to do a lot of different tasks in the main loop. This is a kind of pseudo-multitasking.
Where do I get the value of 100ms from?
It is a compromise between the shortest resolvable time and the number of interrupts.
On the one hand you want to have timers that can be set to a short time, on the other you do not want to waste time in the main loop by checking all the counter-vars every single ms.
I use this kind of timers to refresh lcd every 500ms, for example.
And all kinds of flip and mono-flops, led-blinking and so is easiely made.
It is easyto blink 20 leds almost independently, while getting data from the uart this way. |
|
Back to top |
|
|
for_ro
Joined: 11 Nov 2007 Posts: 260
|
Posted: Fri Oct 25, 2013 5:57 pm Post subject: |
|
|
Arera wrote: |
In the ISR I only (!) set a flag.
In the main loop I check this flag:
|
Hi Arera,
this is often stated, but nevertheless nonsens.
Instead of checking the flag, that was set in the ISR, you can directly check the timer interrupt flag in the main loop.
If there is nothing urgent to be done in an ISR, there is no need to use an ISR.
You will save the whole ISR without any disadvantage. |
|
Back to top |
|
|
Arera
Joined: 23 Sep 2007 Posts: 386 Location: Wuppertal, Germany
|
Posted: Fri Oct 25, 2013 7:43 pm Post subject: |
|
|
At least for beginners, my way might be a bit easier to understand.
The way you describe needs a little knowlede about the regarding registers and how to read and use them.
Where do you reload the timer?
What I really appeciate in Bascom is the fact, that one can get quite far by using only easy to understand high level language.
Marosh seems to be at the same point of programming experience, where I stood after 25 questions in this friendly forum.
Or is there a simple high-level expression to detect that timerx has timed out I missed?
Could you agree, that my way using the ISR is at least not complete nonsens, but one of the roads that lead to Rome?
Else I had to rewrite all my programmes....
Marc |
|
Back to top |
|
|
for_ro
Joined: 11 Nov 2007 Posts: 260
|
Posted: Fri Oct 25, 2013 8:18 pm Post subject: |
|
|
Hi Marc,
of course it works the way you proposed it.
What I would like to say is, that this method is treated as one of the chapters of the bible: Never ever do it differently.
By the way: Using the timer with reload value is another silly thing, which is spread all over the internet, in forums and tutorials.
There is no disadvantage to start the timer at 0 and let it count up to the compare value.
But everyone is using the timer reload way, requiring an ISR to just reload the timer start value.
Funny, but with thousands or millions of hits for this method in the net, it must be better. |
|
Back to top |
|
|
Arera
Joined: 23 Sep 2007 Posts: 386 Location: Wuppertal, Germany
|
Posted: Fri Oct 25, 2013 8:36 pm Post subject: |
|
|
Hi for-ro,
We are getting a bit off topic. I am really interested in the way you handle the timing.
Maybe you could be so kind as to explain it a bit more detailed in a new topic, as a little tutorial?
Marc |
|
Back to top |
|
|
for_ro
Joined: 11 Nov 2007 Posts: 260
|
Posted: Fri Oct 25, 2013 9:13 pm Post subject: |
|
|
Arera wrote: | We are getting a bit off topic. |
Arera wrote: | Where do you reload the timer? |
Sorry, I was just responding to your question.
Arera wrote: | Maybe you could be so kind as to explain it a bit more detailed in a new topic, as a little tutorial? |
I do not think that this would give any new info. It is known as CTC mode, explained in all datasheets and mentioned in the sticks of some better tutorials.
But people are still using the reload method, which incorporates the permanent issue of jeopardizing the timing due to long lasting ISR startup time.
And we all began that way, because we learned from what we read and taught.
But you are right, it is getting off topic. |
|
Back to top |
|
|
Dave
Joined: 05 Feb 2005 Posts: 314 Location: OR
|
Posted: Sat Oct 26, 2013 1:17 am Post subject: |
|
|
The problem is that 'Inputbin Serial_data' inputs one byte then continues through your loop with the 'waitms 1000'. So you see 1...0...2...3 one second apart. ASCII numbers are normally sent with some sort of terminator like a CR. So send '1023<CR>' then you can use input or inkey to get your value. I think this is covered in help. |
|
Back to top |
|
|
Visovian
Joined: 31 Oct 2007 Posts: 584 Location: Czech
|
Posted: Sat Oct 26, 2013 7:39 am Post subject: |
|
|
Try this
Code: | $regfile = "m644pdef.dat"
$crystal = 16000000
$hwstack = 128
$swstack = 64
$framesize = 64
$baud = 9600
Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , _
Db7 = Porta.3 , E = Porta.4 , Rs = Porta.5
Config Lcd = 16x2
Cls
Cursor Off
Config Timer1 = Pwm , Pwm = 10 , Compare_a_pwm = Clear_up , _
Compare_b_pwm = Clear_up , Prescale = 1
Config Porta.6 = Input
Porta.6 = 1 ' pull-up
Tlacitko Alias Pina.6
Dim Serial_data As String * 8
Dim Tempw As Word
Ddrd.5 = 1 ' OC1A output
Ddrd.4 = 1 ' OC1B output
Do
If Ischarwaiting() = 1 Then
Input Serial_data
Cls
Lcd Serial_data
Tempw = Val(serial_data)
Compare1a = Tempw
End If
If Tlacitko = 0 Then
Print "test"
End If
Loop
End |
|
|
Back to top |
|
|
marosh555
Joined: 23 Oct 2012 Posts: 9
|
Posted: Sat Oct 26, 2013 7:44 am Post subject: |
|
|
Hi, thanks all. In main loop I wait 1sec only because that I can see the value on LCD and then I must clear display. I know that this is no good way, but this program is only for testing serial communication. I always use timer for refreshing display |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|